|
1 | | -import type { EnvironmentOptions, RollupCommonJSOptions } from "vite"; |
| 1 | +import type { EnvironmentOptions, RollupCommonJSOptions, Plugin as VitePlugin } from "vite"; |
2 | 2 | import type { NitroPluginContext, ServiceConfig } from "./types.ts"; |
3 | 3 |
|
4 | 4 | import type { RunnerName } from "env-runner"; |
@@ -68,7 +68,10 @@ export function createServiceEnvironment( |
68 | 68 | return { |
69 | 69 | consumer: "server", |
70 | 70 | build: { |
71 | | - rollupOptions: { input: { index: serviceConfig.entry } }, |
| 71 | + rollupOptions: { |
| 72 | + input: { index: serviceConfig.entry }, |
| 73 | + external: [/^nitro(\/|$)/], |
| 74 | + }, |
72 | 75 | minify: ctx.nitro!.options.minify, |
73 | 76 | sourcemap: ctx.nitro!.options.sourcemap, |
74 | 77 | outDir: join(ctx.nitro!.options.buildDir, "vite/services", name), |
@@ -183,6 +186,49 @@ async function _loadRunner(ctx: NitroPluginContext, manager: RunnerManager) { |
183 | 186 | await manager.reload(runner); |
184 | 187 | } |
185 | 188 |
|
| 189 | +// Service environments (e.g. SSR) must not bundle their own copy of `nitro/*` |
| 190 | +// runtime modules. In dev, imports are proxied to the Nitro environment via |
| 191 | +// __VITE_ENVIRONMENT_RUNNER_IMPORT__. In prod, they are externalized (see createServiceEnvironment). |
| 192 | +const NITRO_PROXY_PREFIX = "\0nitro-env-proxy:"; |
| 193 | + |
| 194 | +export function nitroServiceProxy(): VitePlugin { |
| 195 | + return { |
| 196 | + name: "nitro:service-proxy", |
| 197 | + enforce: "pre", |
| 198 | + applyToEnvironment: (env) => env.name !== "nitro" && env.config.consumer === "server", |
| 199 | + apply: (_config, configEnv) => configEnv.command === "serve", |
| 200 | + |
| 201 | + resolveId: { |
| 202 | + filter: { id: /^nitro(\/|$)/ }, |
| 203 | + handler(id) { |
| 204 | + if (id === "nitro" || id.startsWith("nitro/")) { |
| 205 | + return { id: NITRO_PROXY_PREFIX + id, moduleSideEffects: false }; |
| 206 | + } |
| 207 | + }, |
| 208 | + }, |
| 209 | + |
| 210 | + load: { |
| 211 | + filter: { id: /^\0nitro-env-proxy:/ }, |
| 212 | + handler(id) { |
| 213 | + if (!id.startsWith(NITRO_PROXY_PREFIX)) { |
| 214 | + return; |
| 215 | + } |
| 216 | + const originalId = id.slice(NITRO_PROXY_PREFIX.length); |
| 217 | + // __vite_ssr_exportAll__ is provided by the module runner execution context. |
| 218 | + // It re-exports all enumerable own properties (except "default") from the source module. |
| 219 | + return { |
| 220 | + code: [ |
| 221 | + `const _mod = await globalThis.__VITE_ENVIRONMENT_RUNNER_IMPORT__("nitro", ${JSON.stringify(originalId)});`, |
| 222 | + `__vite_ssr_exportAll__(_mod);`, |
| 223 | + `export default _mod.default;`, |
| 224 | + ].join("\n"), |
| 225 | + map: null, |
| 226 | + }; |
| 227 | + }, |
| 228 | + }, |
| 229 | + }; |
| 230 | +} |
| 231 | + |
186 | 232 | // workerd-based runners (miniflare) cannot handle CJS externals via import(), |
187 | 233 | // so all dependencies must be processed through Vite's transform pipeline. |
188 | 234 | function _isWorkerdRunner(ctx: NitroPluginContext): boolean { |
|
0 commit comments