id_verif/server.js

96 lines
2.9 KiB
JavaScript

const express = require("express");
const compression = require("compression");
const path = require("path");
const app = express();
const port = process.env.PORT || 3000;
// Sécurité basique
app.disable("x-powered-by");
// Compression gzip/brotli
app.use(compression());
// Isolation requise pour de meilleures perfs WASM/Workers (Tesseract)
app.use((req, res, next) => {
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
res.setHeader("Cross-Origin-Resource-Policy", "same-origin");
next();
});
// Répertoire statique = dossier courant (contient index.html)
const staticRootDirectory = __dirname;
const nodeModulesDirectory = path.join(__dirname, "node_modules");
const vendorDirectory = path.join(__dirname, "vendor");
app.use(
express.static(staticRootDirectory, {
index: "index.html",
maxAge: "7d",
etag: true,
setHeaders(res, filePath) {
const ext = path.extname(filePath);
if (ext === ".html") {
res.setHeader("Cache-Control", "no-cache");
}
if (ext === ".wasm") {
res.setHeader("Content-Type", "application/wasm");
}
if (ext === ".js") {
res.setHeader("Content-Type", "application/javascript; charset=utf-8");
}
},
})
);
// Assets Tesseract.js auto-hébergés pour éviter les erreurs MIME/CDN
app.use(
"/vendor/tesseract",
express.static(path.join(nodeModulesDirectory, "tesseract.js/dist"), {
maxAge: "7d",
setHeaders(res, filePath) {
const ext = path.extname(filePath);
if (ext === ".wasm") res.setHeader("Content-Type", "application/wasm");
if (ext === ".js") res.setHeader("Content-Type", "application/javascript; charset=utf-8");
},
})
);
app.use(
"/vendor/tesseract-core",
// Le package tesseract.js-core >=4 place les fichiers à la racine du module (pas de dossier dist)
express.static(path.join(nodeModulesDirectory, "tesseract.js-core"), {
maxAge: "7d",
setHeaders(res, filePath) {
const ext = path.extname(filePath);
if (ext === ".wasm") res.setHeader("Content-Type", "application/wasm");
if (ext === ".js") res.setHeader("Content-Type", "application/javascript; charset=utf-8");
},
})
);
// Traineddata (langues) auto-hébergés
app.use(
"/vendor/tessdata",
express.static(path.join(vendorDirectory, "tessdata"), {
maxAge: "30d",
setHeaders(res, filePath) {
const ext = path.extname(filePath);
if (ext === ".gz") res.setHeader("Content-Type", "application/gzip");
if (ext === ".traineddata") res.setHeader("Content-Type", "application/octet-stream");
},
})
);
// Fallback SPA/HTML unique
// Utiliser une regex pour compatibilité avec path-to-regexp (Express 5)
app.get(/.*/, (_req, res) => {
res.sendFile(path.join(staticRootDirectory, "index.html"));
});
app.listen(port, () => {
// eslint-disable-next-line no-console
console.log(`Site statique servi sur http://localhost:${port}`);
});