feat: migrate site to TanStack Start
This commit is contained in:
parent
056daa6460
commit
1bf7b32040
33 changed files with 8684 additions and 1106 deletions
97
server.mjs
Normal file
97
server.mjs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
import { createReadStream } from "node:fs";
|
||||
import { stat } from "node:fs/promises";
|
||||
import { createServer } from "node:http";
|
||||
import { extname, join, normalize } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import startServer from "./dist/server/server.js";
|
||||
|
||||
const root = fileURLToPath(new URL(".", import.meta.url));
|
||||
const clientDir = join(root, "dist", "client");
|
||||
const host = process.env.HOST ?? process.env.WEBSITE_LISTEN_ADDRESS ?? "127.0.0.1";
|
||||
const port = Number(process.env.PORT ?? process.env.WEBSITE_LISTEN_PORT ?? "3002");
|
||||
|
||||
const contentTypes = new Map([
|
||||
[".css", "text/css; charset=utf-8"],
|
||||
[".html", "text/html; charset=utf-8"],
|
||||
[".ico", "image/x-icon"],
|
||||
[".js", "text/javascript; charset=utf-8"],
|
||||
[".json", "application/json; charset=utf-8"],
|
||||
[".png", "image/png"],
|
||||
[".svg", "image/svg+xml"],
|
||||
[".txt", "text/plain; charset=utf-8"],
|
||||
[".woff", "font/woff"],
|
||||
]);
|
||||
|
||||
function writeResponse(res, response) {
|
||||
res.writeHead(response.status, Object.fromEntries(response.headers));
|
||||
if (!response.body) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
response.body.pipeTo(
|
||||
new WritableStream({
|
||||
write(chunk) {
|
||||
res.write(chunk);
|
||||
},
|
||||
close() {
|
||||
res.end();
|
||||
},
|
||||
abort(error) {
|
||||
res.destroy(error);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async function tryServeStatic(req, res, pathname) {
|
||||
if (pathname === "/" || !extname(pathname)) return false;
|
||||
|
||||
const decoded = decodeURIComponent(pathname);
|
||||
const normalized = normalize(decoded).replace(/^\.\.(\/|$)/, "");
|
||||
const filePath = join(clientDir, normalized);
|
||||
|
||||
if (!filePath.startsWith(clientDir)) return false;
|
||||
|
||||
try {
|
||||
const fileStat = await stat(filePath);
|
||||
if (!fileStat.isFile()) return false;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
res.writeHead(200, {
|
||||
"Content-Type": contentTypes.get(extname(filePath)) ?? "application/octet-stream",
|
||||
"Cache-Control": filePath.includes("/assets/")
|
||||
? "public, max-age=31536000, immutable"
|
||||
: "no-store",
|
||||
});
|
||||
createReadStream(filePath).pipe(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
createServer(async (req, res) => {
|
||||
try {
|
||||
const origin = `http://${req.headers.host ?? `${host}:${port}`}`;
|
||||
const url = new URL(req.url ?? "/", origin);
|
||||
|
||||
if (req.method === "GET" || req.method === "HEAD") {
|
||||
const served = await tryServeStatic(req, res, url.pathname);
|
||||
if (served) return;
|
||||
}
|
||||
|
||||
const request = new Request(url, {
|
||||
method: req.method,
|
||||
headers: req.headers,
|
||||
body: req.method === "GET" || req.method === "HEAD" ? undefined : req,
|
||||
duplex: "half",
|
||||
});
|
||||
const response = await startServer.fetch(request);
|
||||
writeResponse(res, response);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
res.writeHead(500, { "Content-Type": "text/plain; charset=utf-8" });
|
||||
res.end("Internal Server Error");
|
||||
}
|
||||
}).listen(port, host, () => {
|
||||
console.log(`Listening on http://${host}:${port}`);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue