const http = require("node:http"); // A small multi-file app whose markup uses absolute paths, as real apps do. const files = { "/style.css": ["text/css", `@import "/more.css";\n`], "/more.css": ["text/css", `#hi { color: rgb(1, 2, 3) }\n`], "/lib.js": ["text/javascript", `export const text = "from lib.js";\n`], "/app.js": ["text/javascript", `import { text } from "/lib.js"; document.getElementById("js").textContent = text; fetch("/api/data").then((r) => r.json()).then((d) => { document.getElementById("api").textContent = String(d.n); }); new Worker("/w.js").onmessage = (e) => { document.getElementById("worker").textContent = "worker:" + e.data; }; `], "/w.js": ["text/javascript", `fetch("/api/data").then((r) => r.json()).then((d) => postMessage(d.n));\n`], "/api/data": ["application/json", JSON.stringify({ n: 42 })], "/about": ["text/html", `
${body}
`); }); return; } const file = req.method === "GET" && files[req.url]; if (file) { res.writeHead(200, { "content-type": `${file[0]}; charset=utf-8` }); res.end(file[1]); return; } if (req.method === "POST" && req.url.startsWith("/echo")) { let body = ""; const dec = new TextDecoder(); req.on("data", (chunk) => { body += dec.decode(chunk, { stream: true }); }); req.on("end", () => { res.setHeader("x-nib", "1"); res.writeHead(200, { "content-type": "text/plain; charset=utf-8" }); res.end(body); }); return; } if (req.url === "/bye") { res.writeHead(200, { "content-type": "text/plain; charset=utf-8" }); res.end("bye\n"); server.close(() => console.log("closed")); return; } res.writeHead(200, { "content-type": "text/html; charset=utf-8" }); const hi = `