diff --git a/.changeset/moody-hands-check.md b/.changeset/moody-hands-check.md new file mode 100644 index 000000000..fde7ef434 --- /dev/null +++ b/.changeset/moody-hands-check.md @@ -0,0 +1,5 @@ +--- +"@solidjs/start": minor +--- + +add `vite preview` support diff --git a/packages/start/src/config/dev-server.ts b/packages/start/src/config/dev-server.ts index 6d783312e..15aac15d8 100644 --- a/packages/start/src/config/dev-server.ts +++ b/packages/start/src/config/dev-server.ts @@ -6,11 +6,53 @@ import { type ViteDevServer, } from "vite"; import { VITE_ENVIRONMENTS } from "./constants.ts"; +import { join, resolve } from "node:path"; +import { H3, serveStatic } from "h3"; +import { stat, readFile } from "node:fs/promises"; + +type Server = { + default: { fetch: (req: Request) => Promise }; +}; export function devServer(): Array { return [ { name: "solid-start-dev-server", + async configurePreviewServer(vitePreviewServer) { + const { default: h3App }: Server = await import( + resolve(process.cwd(), "dist/server/entry-server.js") + ); + const app = new H3(); + app.use("/_build/**", event => { + return serveStatic(event, { + indexNames: ["/index.html"], + headers: { "cache-control": "public, max-age=3156000, immutable" }, + getContents: id => readFile(join(process.cwd(), "dist/client", id)), + getMeta: async id => { + const stats = await stat(join("dist/client", id)).catch(() => {}); + if (stats?.isFile()) { + return { + size: stats.size, + mtime: stats.mtimeMs, + }; + } + }, + }); + }); + app.mount("/", h3App); + + return async () => { + vitePreviewServer.middlewares.use(async (req, res) => { + // fix streaming because vite uses gzip by default + res.setHeader("Content-Encoding", "identity"); + + const webReq = new NodeRequest({ req, res }); + + const webRes = await app.fetch(webReq); + sendNodeResponse(res, webRes); + }); + }; + }, configureServer(viteDevServer) { (globalThis as any).VITE_DEV_SERVER = viteDevServer; return async () => { @@ -40,9 +82,7 @@ export function devServer(): Array { const webReq = new NodeRequest({ req, res }); try { - const serverEntry: { - default: { fetch: (req: Request) => Promise }; - } = await serverEnv.runner.import("./src/entry-server.tsx"); + const serverEntry: Server = await serverEnv.runner.import("./src/entry-server.tsx"); const webRes = await serverEntry.default.fetch(webReq);