Files

69 lines
2.1 KiB
JavaScript

// Статический сервер для e2e (Playwright webServer). Раздаёт web/build
// (adapter-static): /foo -> foo.html | foo/index.html, MIME по расширению.
// Запуск: pnpm build && node scripts/serve-static.mjs --port 4173
import { createServer } from "node:http";
import { readFileSync, existsSync, statSync } from "node:fs";
import { extname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const portIndex = process.argv.indexOf("--port");
const PORT =
portIndex >= 0 ? Number(process.argv[portIndex + 1]) || 4173 : 4173;
const ROOT = fileURLToPath(new URL("../build", import.meta.url));
const MIME = {
".html": "text/html; charset=utf-8",
".js": "text/javascript",
".mjs": "text/javascript",
".css": "text/css",
".json": "application/json",
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".webp": "image/webp",
".svg": "image/svg+xml",
".ico": "image/x-icon",
".woff2": "font/woff2",
".woff": "font/woff",
".ttf": "font/ttf",
".txt": "text/plain; charset=utf-8",
".xml": "application/xml",
".map": "application/json",
};
function candidates(pathname) {
const rel = pathname.replace(/\\/g, "/").replace(/^\/+/, "");
const base = rel ? join(ROOT, ...rel.split("/")) : ROOT;
const out = [base];
if (!extname(base)) {
out.push(`${base}.html`);
out.push(join(base, "index.html"));
}
return out;
}
function serve(req, res) {
const url = new URL(req.url, `http://${req.headers.host}`);
const path = decodeURIComponent(url.pathname);
for (const file of candidates(path)) {
try {
if (!statSync(file).isFile()) continue;
const body = readFileSync(file);
res.writeHead(200, {
"Content-Type": MIME[extname(file)] ?? "application/octet-stream",
"Cache-Control": "no-store",
});
res.end(body);
return;
} catch {
/* not found — try next candidate */
}
}
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
res.end("Not found: " + path);
}
createServer(serve).listen(PORT, "127.0.0.1", () => {
console.log(`[serve-static] serving ${ROOT} on http://127.0.0.1:${PORT}`);
});