[READ-ONLY] Mirror of https://github.com/danielroe/nitro-vite-repros.
0

Configure Feed

Select the types of activity you want to include in your feed.

nitro-vite-repros / vite.config.ts
3.7 kB 85 lines
1import { fileURLToPath } from 'node:url' 2import { defineConfig } from 'vite' 3import { nitro } from 'nitro/vite' 4import type { Nitro } from 'nitro/types' 5 6const rendererEntry = fileURLToPath(new URL('./src/renderer.ts', import.meta.url)) 7const globalCss = fileURLToPath(new URL('./src/app/assets/global.css', import.meta.url)) 8 9export default defineConfig({ 10 plugins: [ 11 nitro({ 12 runtimeConfig: { public: { probe: 'hello-from-runtime-config' } }, 13 prerender: { routes: ['/', '/prerendered'] }, 14 }), 15 { 16 // A Vite plugin that owns a custom virtual-module scheme, scoped 17 // to server-consumer envs. The ssr env build resolves these via 18 // the plugin pipeline; the deployable's nitro env rebundle does 19 // the same. The prerender Nitro does not, because it builds with 20 // standalone rolldown (see https://github.com/nitrojs/nitro/pull/4152 21 // for the related `nitro/*` proxy plumbing in service envs). 22 name: 'repro:virtual-fs', 23 enforce: 'pre', 24 applyToEnvironment: env => env.config.consumer === 'server', 25 resolveId: { 26 filter: { id: /^#virtual\// }, 27 handler (id) { return '\0' + id }, 28 }, 29 load: { 30 filter: { id: /^\0#virtual\// }, 31 handler (id) { 32 if (id === '\0#virtual/entry') return 'export default "live-entry-content"' 33 if (id === '\0#virtual/css') { 34 return `import ${JSON.stringify(globalCss)}\nexport default "css-loaded"` 35 } 36 }, 37 }, 38 }, 39 { 40 // Mirror of the proxy plumbing landed in 41 // https://github.com/nitrojs/nitro/pull/4152: service environments 42 // must not bundle their own copy of `nitro/*` runtime modules, 43 // otherwise the ssr entry gets stub instances instead of sharing 44 // the Nitro environment's runtime state. The PR externalises 45 // `/^nitro(\/|$)/` from service envs in prod and proxies them via 46 // `__VITE_ENVIRONMENT_RUNNER_IMPORT__` in dev. 47 // 48 // In dev, Vite's env-runner short-circuits externalised 49 // bare-specifier imports to Node before the proxy plugin runs. 50 // `noExternal` here forces `nitro/*` through the plugin pipeline 51 // so the proxy can claim them. Without this, `useRuntimeConfig()` 52 // in dev returns `{ app: {}, nitro: {} }` (the stub at 53 // `nitro/dist/runtime/virtual/runtime-config.mjs`). 54 name: 'repro:noExternal-nitro', 55 configEnvironment (name) { 56 if (name !== 'ssr') return 57 return { resolve: { noExternal: [/^nitro(\/|$)/] } } 58 }, 59 }, 60 { 61 // Wire `src/renderer.ts` as the prerender Nitro's `/**` handler 62 // via a `.nitro` module hook (the shape `nitro/vite` scans for in 63 // `nitro/dist/vite.mjs`). 64 // 65 // The prerender Nitro spins up via 66 // `createNitro(prerendererConfig)` and builds with standalone 67 // rolldown when the main builder is `vite`, so none of the Vite 68 // plugins above reach it. The static chain 69 // `renderer.ts -> app/entry.ts -> #virtual/css` is unresolved in 70 // the prerender bundle; rolldown leaves the bare specifier in the 71 // output and Node errors at prerender runtime with 72 // `ERR_PACKAGE_IMPORT_NOT_DEFINED`. See README for the trace. 73 // 74 // Comment this plugin out to make the build succeed (without any 75 // prerendering — every prerender route 404s instead of 500ing). 76 name: 'repro:prerender-handler', 77 nitro: (nitroInstance: Nitro) => { 78 nitroInstance.hooks.hook('prerender:config', (prerendererConfig) => { 79 if (prerendererConfig.renderer) return 80 prerendererConfig.renderer = { handler: rendererEntry } 81 }) 82 }, 83 }, 84 ], 85})