server.mjs 1.4 KB

1234567891011121314151617181920212223242526272829
  1. // 本地预览:node server.mjs → http://localhost:4173
  2. // 仅用于演示与截图,不参与任何构建。
  3. import { createServer } from 'node:http';
  4. import { readFile, stat } from 'node:fs/promises';
  5. import { extname, join, normalize } from 'node:path';
  6. const ROOT = new URL('.', import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, '$1');
  7. const PORT = Number(process.env.PORT || 4173);
  8. const TYPES = {
  9. '.html': 'text/html; charset=utf-8', '.css': 'text/css; charset=utf-8',
  10. '.js': 'text/javascript; charset=utf-8', '.svg': 'image/svg+xml',
  11. '.woff2': 'font/woff2', '.json': 'application/json',
  12. };
  13. createServer(async (req, res) => {
  14. const url = decodeURIComponent((req.url || '/').split('?')[0]);
  15. let path = normalize(join(ROOT, url === '/' ? 'index.html' : url));
  16. if (!path.startsWith(normalize(ROOT))) { res.writeHead(403).end(); return; }
  17. try {
  18. const info = await stat(path);
  19. if (info.isDirectory()) path = join(path, 'index.html');
  20. const body = await readFile(path);
  21. res.writeHead(200, { 'content-type': TYPES[extname(path)] || 'application/octet-stream', 'cache-control': 'no-store' });
  22. res.end(body);
  23. } catch {
  24. const body = await readFile(join(ROOT, '404.html')).catch(() => 'Not found');
  25. res.writeHead(404, { 'content-type': 'text/html; charset=utf-8' }).end(body);
  26. }
  27. }).listen(PORT, () => console.log(`Fmode 落地页预览: http://localhost:${PORT}`));