From 827e40dfc4056064aae150a92b62357b06af3da8 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Thu, 15 Jan 2026 12:40:43 +0900 Subject: [PATCH] feat(bundled-dev): support worker in initial bundle --- packages/vite/src/node/plugins/asset.ts | 35 ++++++++++++++++-------- packages/vite/src/node/plugins/worker.ts | 22 +++++++++++---- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index b14a0b78e0228f..d8ea8a441506a9 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -40,6 +40,7 @@ import { withTrailingSlash, } from '../../shared/utils' import type { Environment } from '../environment' +import type { PartialEnvironment } from '../baseEnvironment' // referenceId is base64url but replaces - with $ export const assetUrlRE: RegExp = /__VITE_ASSET__([\w$]+)__(?:\$_(.*?)__)?/g @@ -473,18 +474,7 @@ async function fileToBuiltUrl( environment.config.experimental.bundledDev ) { const outputFilename = pluginContext.getFileName(referenceId) - const outputUrl = toOutputFilePathInJS( - environment, - outputFilename, - 'asset', - 'assets/dummy.js', - 'js', - () => { - throw new Error('unreachable') - }, - ) - if (typeof outputUrl === 'object') throw new Error('unreachable') - url = outputUrl + url = toOutputFilePathInJSForBundledDev(environment, outputFilename) } else { url = `__VITE_ASSET__${referenceId}__${postfix ? `$_${postfix}__` : ``}` } @@ -494,6 +484,27 @@ async function fileToBuiltUrl( return url } +export function toOutputFilePathInJSForBundledDev( + environment: PartialEnvironment, + filename: string, +): string { + const outputUrl = toOutputFilePathInJS( + environment, + filename, + 'asset', + // in bundled dev, the chunks are always emitted to `assets` directory + 'assets/dummy.js', + 'js', + // relative base is not supported in bundled dev + () => { + throw new Error('unreachable') + }, + ) + // renderBuiltUrl is not supported in bundled dev + if (typeof outputUrl === 'object') throw new Error('unreachable') + return outputUrl +} + export async function urlToBuiltUrl( pluginContext: PluginContext, url: string, diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index 9f82c0bc2668c6..3a042353379ad7 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -25,7 +25,7 @@ import { } from '../build' import { cleanUrl } from '../../shared/utils' import type { Logger } from '../logger' -import { fileToUrl } from './asset' +import { fileToUrl, toOutputFilePathInJSForBundledDev } from './asset' type WorkerBundle = { entryFilename: string @@ -401,7 +401,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { const { format } = config.worker const workerConstructor = workerMatch[1] === 'sharedworker' ? 'SharedWorker' : 'Worker' - const workerType = isBuild + const workerType = config.isBundled ? format === 'es' ? 'module' : 'classic' @@ -412,7 +412,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { }` let urlCode: string - if (isBuild) { + if (config.isBundled) { if (isWorker && config.bundleChain.at(-1) === cleanUrl(id)) { urlCode = 'self.location.href' } else if (inlineRE.test(id)) { @@ -467,7 +467,19 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { } } else { const result = await workerFileToUrl(config, id) - urlCode = JSON.stringify(result.entryUrlPlaceholder) + let url: string + if ( + this.environment.config.command === 'serve' && + this.environment.config.experimental.bundledDev + ) { + url = toOutputFilePathInJSForBundledDev( + this.environment, + result.entryFilename, + ) + } else { + url = result.entryUrlPlaceholder + } + urlCode = JSON.stringify(url) for (const file of result.watchedFiles) { this.addWatchFile(file) } @@ -517,7 +529,7 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { const scriptPath = JSON.stringify(ENV_PUBLIC_PATH) injectEnv = `import ${scriptPath}\n` } else if (workerType === 'ignore') { - if (isBuild) { + if (config.isBundled) { injectEnv = '' } else { // dynamic worker type we can't know how import the env