96 lines
2.9 KiB
JavaScript
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}`);
|
|
});
|