diff --git a/packages/vite/src/node/__tests__/plugins/workerImportMetaUrl.spec.ts b/packages/vite/src/node/__tests__/plugins/workerImportMetaUrl.spec.ts index 348e3e39be0147..517947b1800667 100644 --- a/packages/vite/src/node/__tests__/plugins/workerImportMetaUrl.spec.ts +++ b/packages/vite/src/node/__tests__/plugins/workerImportMetaUrl.spec.ts @@ -253,4 +253,14 @@ new Worker( )" `) }) + + test('preserves custom search params in worker URL', async () => { + expect( + await transform( + 'new Worker(new URL("./worker.js?foo=bar&baz=qux", import.meta.url), { type: "module" })', + ), + ).toMatchInlineSnapshot( + '"new Worker(new URL(/* @vite-ignore */ "/worker.js?worker_file&type=module&foo=bar&baz=qux", \'\' + import.meta.url), { type: "module" })"', + ) + }) }) diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index b868df50d392f9..c974817ac1269d 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -23,7 +23,7 @@ import { onRollupLog, toOutputFilePathInJS, } from '../build' -import { cleanUrl } from '../../shared/utils' +import { cleanUrl, splitFileAndPostfix } from '../../shared/utils' import type { Logger } from '../logger' import { fileToUrl, toOutputFilePathInJSForBundledDev } from './asset' @@ -156,6 +156,23 @@ export const workerOrSharedWorkerRE: RegExp = const workerFileRE = /(?:\?|&)worker_file&type=(\w+)(?:&|$)/ const inlineRE = /[?&]inline\b/ +function getWorkerRequestPostfix(id: string): string { + const { postfix } = splitFileAndPostfix(id) + if (!postfix || postfix[0] !== '?') { + return '' + } + + const queryParams = new URLSearchParams(postfix.slice(1)) + + queryParams.delete('worker') + queryParams.delete('sharedworker') + queryParams.delete('inline') + queryParams.delete('url') + + const customQuery = queryParams.toString() + return customQuery ? `?${customQuery}` : '' +} + export const WORKER_FILE_ID = 'worker_file' const workerOutputCaches = new WeakMap() @@ -489,8 +506,12 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { } } } else { + const workerRequestPostfix = getWorkerRequestPostfix(id) let url = await fileToUrl(this, cleanUrl(id)) - url = injectQuery(url, `${WORKER_FILE_ID}&type=${workerType}`) + url = injectQuery( + `${url}${workerRequestPostfix}`, + `${WORKER_FILE_ID}&type=${workerType}`, + ) urlCode = JSON.stringify(url) } diff --git a/packages/vite/src/node/plugins/workerImportMetaUrl.ts b/packages/vite/src/node/plugins/workerImportMetaUrl.ts index 55d28d17e0f97b..48150dcc4ea1e6 100644 --- a/packages/vite/src/node/plugins/workerImportMetaUrl.ts +++ b/packages/vite/src/node/plugins/workerImportMetaUrl.ts @@ -9,7 +9,7 @@ import type { Plugin } from '../plugin' import { evalValue, injectQuery, transformStableResult } from '../utils' import { createBackCompatIdResolver } from '../idResolver' import type { ResolveIdFn } from '../idResolver' -import { cleanUrl, slash } from '../../shared/utils' +import { cleanUrl, slash, splitFileAndPostfix } from '../../shared/utils' import type { WorkerType } from './worker' import { WORKER_FILE_ID, workerFileToUrl } from './worker' import { fileToUrl, toOutputFilePathInJSForBundledDev } from './asset' @@ -229,9 +229,11 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { s ||= new MagicString(code) const workerType = await getWorkerType(code, cleanString, endIndex) const url = rawUrl.slice(1, -1) + const { file: urlWithoutPostfix, postfix } = splitFileAndPostfix(url) + const queryPostfix = postfix[0] === '?' ? postfix : '' let file: string | undefined - if (url[0] === '.') { - file = path.resolve(path.dirname(id), url) + if (urlWithoutPostfix[0] === '.') { + file = path.resolve(path.dirname(id), urlWithoutPostfix) file = slash(tryFsResolve(file, fsResolveOptions) ?? file) } else { workerResolver ??= createBackCompatIdResolver(config, { @@ -239,11 +241,11 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { tryIndex: false, preferRelative: true, }) - file = await workerResolver(this.environment, url, id) + file = await workerResolver(this.environment, urlWithoutPostfix, id) file ??= - url[0] === '/' - ? slash(path.join(config.publicDir, url)) - : slash(path.resolve(path.dirname(id), url)) + urlWithoutPostfix[0] === '/' + ? slash(path.join(config.publicDir, urlWithoutPostfix)) + : slash(path.resolve(path.dirname(id), urlWithoutPostfix)) } if ( @@ -273,7 +275,7 @@ export function workerImportMetaUrlPlugin(config: ResolvedConfig): Plugin { } else { builtUrl = await fileToUrl(this, cleanUrl(file)) builtUrl = injectQuery( - builtUrl, + `${builtUrl}${queryPostfix}`, `${WORKER_FILE_ID}&type=${workerType}`, ) }