(server)
| 13 | // Run last so platform plugins (Cloudflare, Vercel, etc.) can register their handlers first |
| 14 | order: 'post', |
| 15 | handler(server) { |
| 16 | // Return a function so Vite's internal middlewares (static files, etc.) handle requests first. |
| 17 | // Our SSR handler only processes requests that nothing else handled. |
| 18 | return () => { |
| 19 | // Cache the server build to avoid re-importing on every request |
| 20 | let serverBuild: any = null |
| 21 | |
| 22 | server.middlewares.use(async (req, res, next) => { |
| 23 | try { |
| 24 | // Lazy load server build on first request |
| 25 | if (!serverBuild) { |
| 26 | // Derive output filename from input |
| 27 | const serverEnv = |
| 28 | server.config.environments[VITE_ENVIRONMENT_NAMES.server] |
| 29 | const serverInput = |
| 30 | serverEnv?.build.rollupOptions.input ?? 'server' |
| 31 | |
| 32 | if (typeof serverInput !== 'string') { |
| 33 | throw new Error('Invalid server input. Expected a string.') |
| 34 | } |
| 35 | |
| 36 | // Get basename without extension and add .js |
| 37 | const outputFilename = `${basename(serverInput, extname(serverInput))}.js` |
| 38 | const serverOutputDir = getServerOutputDirectory(server.config) |
| 39 | const serverEntryPath = join(serverOutputDir, outputFilename) |
| 40 | const imported = await import( |
| 41 | pathToFileURL(serverEntryPath).toString() |
| 42 | ) |
| 43 | |
| 44 | serverBuild = imported.default |
| 45 | } |
| 46 | |
| 47 | // Prepend base path to request URL to match routing setup |
| 48 | req.url = joinURL(server.config.base, req.url ?? '/') |
| 49 | |
| 50 | const webReq = new NodeRequest({ req, res }) |
| 51 | const webRes: Response = await serverBuild.fetch(webReq) |
| 52 | |
| 53 | // Temporary workaround |
| 54 | // Vite preview's compression middleware doesn't support flattened array headers that srvx sets |
| 55 | // Call writeHead() before srvx to avoid corruption |
| 56 | res.setHeaders(webRes.headers) |
| 57 | res.writeHead(webRes.status, webRes.statusText) |
| 58 | |
| 59 | return sendNodeResponse(res, webRes) |
| 60 | } catch (error) { |
| 61 | next(error) |
| 62 | } |
| 63 | }) |
| 64 | } |
| 65 | }, |
| 66 | }, |
| 67 | } |
| 68 | } |
nothing calls this directly
no test coverage detected