First demo
This commit is contained in:
66
server.ts
Normal file
66
server.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import { serve } from "bun";
|
||||
|
||||
const port = Number(process.env.PORT ?? "3000");
|
||||
|
||||
function contentType(pathname: string): string | undefined {
|
||||
if (pathname.endsWith(".html")) return "text/html; charset=utf-8";
|
||||
if (pathname.endsWith(".css")) return "text/css; charset=utf-8";
|
||||
if (pathname.endsWith(".js")) return "application/javascript; charset=utf-8";
|
||||
if (pathname.endsWith(".mjs")) return "application/javascript; charset=utf-8";
|
||||
if (pathname.endsWith(".json")) return "application/json; charset=utf-8";
|
||||
if (pathname.endsWith(".svg")) return "image/svg+xml";
|
||||
if (pathname.endsWith(".png")) return "image/png";
|
||||
if (pathname.endsWith(".jpg") || pathname.endsWith(".jpeg")) return "image/jpeg";
|
||||
if (pathname.endsWith(".webp")) return "image/webp";
|
||||
if (pathname.endsWith(".ico")) return "image/x-icon";
|
||||
if (pathname.endsWith(".woff")) return "font/woff";
|
||||
if (pathname.endsWith(".woff2")) return "font/woff2";
|
||||
if (pathname.endsWith(".txt")) return "text/plain; charset=utf-8";
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const distDir = `${process.cwd()}/dist`;
|
||||
|
||||
serve({
|
||||
port,
|
||||
async fetch(req) {
|
||||
const url = new URL(req.url);
|
||||
|
||||
// Normalize paths
|
||||
let pathname = decodeURIComponent(url.pathname);
|
||||
|
||||
// Default document
|
||||
if (pathname === "/") pathname = "/index.html";
|
||||
|
||||
const filePath = `${distDir}${pathname}`;
|
||||
|
||||
// Try direct file first
|
||||
let file = Bun.file(filePath);
|
||||
if (!(await file.exists())) {
|
||||
// If request is for a "route", serve index.html (SPA-ish fallback)
|
||||
// Astro static pages typically exist as real files, but this fallback helps
|
||||
// if you add client-side routing later.
|
||||
file = Bun.file(`${distDir}/index.html`);
|
||||
if (!(await file.exists())) {
|
||||
return new Response("Not Found", { status: 404 });
|
||||
}
|
||||
}
|
||||
|
||||
const headers = new Headers();
|
||||
const ct = contentType(pathname);
|
||||
if (ct) headers.set("Content-Type", ct);
|
||||
|
||||
// Cache policy:
|
||||
// - HTML: no-cache (so updates show quickly)
|
||||
// - assets: cache long (Astro fingerprints assets by default)
|
||||
if (pathname.endsWith(".html")) {
|
||||
headers.set("Cache-Control", "no-cache");
|
||||
} else {
|
||||
headers.set("Cache-Control", "public, max-age=31536000, immutable");
|
||||
}
|
||||
|
||||
return new Response(file, { headers });
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Serving dist on http://0.0.0.0:${port}`);
|
||||
Reference in New Issue
Block a user