29 lines
1.5 KiB
JavaScript
29 lines
1.5 KiB
JavaScript
// tools/serve.mjs [port] [folder]: serve the page on 127.0.0.1, for the build's screenshots and for trying it locally.
|
|
// Static files only, nothing outside the folder; no dependencies beyond node.
|
|
|
|
import { createServer } from 'node:http';
|
|
import { readFile, stat } from 'node:fs/promises';
|
|
import { extname, join, resolve, sep } from 'node:path';
|
|
|
|
const port = Number(process.argv[2] || 8000);
|
|
const root = resolve(process.argv[3] || '.');
|
|
const TYPES = {
|
|
'.html': 'text/html; charset=utf-8', '.css': 'text/css; charset=utf-8', '.js': 'text/javascript; charset=utf-8',
|
|
'.mjs': 'text/javascript; charset=utf-8', '.json': 'application/json', '.svg': 'image/svg+xml', '.png': 'image/png',
|
|
'.woff': 'font/woff', '.woff2': 'font/woff2', '.txt': 'text/plain; charset=utf-8', '.md': 'text/markdown; charset=utf-8',
|
|
};
|
|
|
|
createServer(async (req, res) => {
|
|
try {
|
|
let file = resolve(join(root, decodeURIComponent(new URL(req.url, 'http://localhost').pathname)));
|
|
if (file !== root && !file.startsWith(root + sep)) throw new Error('outside the folder');
|
|
if ((await stat(file)).isDirectory()) file = join(file, 'index.html');
|
|
const body = await readFile(file);
|
|
res.writeHead(200, { 'content-type': TYPES[extname(file)] || 'application/octet-stream', 'cache-control': 'no-store' });
|
|
res.end(req.method === 'HEAD' ? undefined : body);
|
|
} catch {
|
|
res.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' });
|
|
res.end('not found\n');
|
|
}
|
|
}).listen(port, '127.0.0.1', () => console.log(`serving ${root} at http://127.0.0.1:${port}/`));
|