diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index 9751630d627ef8..dfb7e063ccac2e 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -24,6 +24,7 @@ import type { WatcherOptions, } from 'rolldown' import { viteLoadFallbackPlugin as nativeLoadFallbackPlugin } from 'rolldown/experimental' +import { esmExternalRequirePlugin } from 'rolldown/plugins' import type { EsbuildTarget } from '#types/internal/esbuildOptions' import type { RollupCommonJSOptions } from '#dep-types/commonjs' import type { RollupDynamicImportVarsOptions } from '#dep-types/dynamicImportVars' @@ -420,6 +421,7 @@ export function resolveBuildEnvironmentOptions( logger: Logger, consumer: 'client' | 'server' | undefined, isBundledDev: boolean, + isSsrTargetWebworkerEnvironment?: boolean, ): ResolvedBuildEnvironmentOptions { const deprecatedPolyfillModulePreload = raw.polyfillModulePreload const { polyfillModulePreload, ...rest } = raw @@ -451,7 +453,10 @@ export function resolveBuildEnvironmentOptions( ) setupRollupOptionCompat(merged, 'build') merged.rolldownOptions = { - platform: consumer === 'server' ? 'node' : 'browser', + platform: + consumer === 'client' || isSsrTargetWebworkerEnvironment + ? 'browser' + : 'node', ...merged.rolldownOptions, } @@ -654,6 +659,12 @@ export function resolveRolldownOptions( environment.name === 'ssr' && environment.getTopLevelConfig().ssr?.target === 'webworker' + // For webworker SSR with platform: 'browser', external CJS require() calls + // need to be converted to ESM imports since createRequire is not available. + if (isSsrTargetWebworkerEnvironment) { + plugins.push(esmExternalRequirePlugin()) + } + const buildOutputOptions = (output: OutputOptions = {}): OutputOptions => { // @ts-expect-error See https://github.com/vitejs/vite/issues/5812#issuecomment-984345618 if (output.output) { diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index 211217defd62ef..9e31a35bd7f4e5 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -969,6 +969,7 @@ function resolveEnvironmentOptions( logger, consumer, isBundledDev, + isSsrTargetWebworkerEnvironment, ), plugins: undefined!, // to be resolved later // will be set by `setOptimizeDepsPluginNames` later diff --git a/playground/ssr-webworker/__tests__/ssr-webworker.spec.ts b/playground/ssr-webworker/__tests__/ssr-webworker.spec.ts index d1362bc16e3003..22b1d1ca4511e7 100644 --- a/playground/ssr-webworker/__tests__/ssr-webworker.spec.ts +++ b/playground/ssr-webworker/__tests__/ssr-webworker.spec.ts @@ -30,6 +30,12 @@ test('supports nodejs_compat', async () => { ) }) +test.runIf(isBuild)('build output does not contain createRequire', async () => { + const workerContent = findAssetFile(/entry-worker/, 'worker', '') + expect(workerContent).toBeDefined() + expect(workerContent).not.toContain('createRequire') +}) + test.runIf(isBuild)('codeSplitting: false', () => { const dynamicJsContent = findAssetFile(/dynamic-[-\w]+\.js/, 'worker') expect(dynamicJsContent).toBeUndefined()