From ed1ec6240d12b2ba550a8cae40802ef6f9c615e5 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Fri, 5 Dec 2025 20:09:20 +0900 Subject: [PATCH 1/5] fix: don't strip base from imports --- packages/vite/src/node/plugins/importAnalysis.ts | 2 -- packages/vite/src/node/plugins/worker.ts | 9 +++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 89e9243423dfc8..a31c989c9d2a5a 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -326,8 +326,6 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { pos: number, forceSkipImportAnalysis: boolean = false, ): Promise<[string, string | null]> => { - url = stripBase(url, base) - let importerFile = importer if ( diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index e311b93fd27168..5730a5b321c0e9 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -507,13 +507,14 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { const workerType = workerFileMatch[1] as WorkerType let injectEnv = '' - const scriptPath = JSON.stringify( - path.posix.join(config.base, ENV_PUBLIC_PATH), - ) - if (workerType === 'classic') { + // base needs to be joined as the base is not injected to `importScripts` automatically + const scriptPath = JSON.stringify( + path.posix.join(config.base, ENV_PUBLIC_PATH), + ) injectEnv = `importScripts(${scriptPath})\n` } else if (workerType === 'module') { + const scriptPath = JSON.stringify(ENV_PUBLIC_PATH) injectEnv = `import ${scriptPath}\n` } else if (workerType === 'ignore') { if (isBuild) { From 8130d97e63b6f8ace850676a04c974aa21ec7d51 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:10:48 +0900 Subject: [PATCH 2/5] Revert "fix: don't strip base from imports" This reverts commit ed1ec6240d12b2ba550a8cae40802ef6f9c615e5. --- packages/vite/src/node/plugins/importAnalysis.ts | 2 ++ packages/vite/src/node/plugins/worker.ts | 9 ++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index a31c989c9d2a5a..89e9243423dfc8 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -326,6 +326,8 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { pos: number, forceSkipImportAnalysis: boolean = false, ): Promise<[string, string | null]> => { + url = stripBase(url, base) + let importerFile = importer if ( diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index 5730a5b321c0e9..e311b93fd27168 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -507,14 +507,13 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { const workerType = workerFileMatch[1] as WorkerType let injectEnv = '' + const scriptPath = JSON.stringify( + path.posix.join(config.base, ENV_PUBLIC_PATH), + ) + if (workerType === 'classic') { - // base needs to be joined as the base is not injected to `importScripts` automatically - const scriptPath = JSON.stringify( - path.posix.join(config.base, ENV_PUBLIC_PATH), - ) injectEnv = `importScripts(${scriptPath})\n` } else if (workerType === 'module') { - const scriptPath = JSON.stringify(ENV_PUBLIC_PATH) injectEnv = `import ${scriptPath}\n` } else if (workerType === 'ignore') { if (isBuild) { From 1b62738728c18f55f07bb838bbcb968c085b8440 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:09:53 +0900 Subject: [PATCH 3/5] test: add test case --- .../base-conflict/__tests__/base-conflict.ts | 6 ++++ playground/base-conflict/index.html | 11 +++++++ playground/base-conflict/package.json | 12 +++++++ playground/base-conflict/src/importee.ts | 1 + playground/base-conflict/src/main.ts | 3 ++ .../base-conflict/src/virtualModules.d.ts | 4 +++ playground/base-conflict/vite.config.ts | 32 +++++++++++++++++++ pnpm-lock.yaml | 2 ++ 8 files changed, 71 insertions(+) create mode 100644 playground/base-conflict/__tests__/base-conflict.ts create mode 100644 playground/base-conflict/index.html create mode 100644 playground/base-conflict/package.json create mode 100644 playground/base-conflict/src/importee.ts create mode 100644 playground/base-conflict/src/main.ts create mode 100644 playground/base-conflict/src/virtualModules.d.ts create mode 100644 playground/base-conflict/vite.config.ts diff --git a/playground/base-conflict/__tests__/base-conflict.ts b/playground/base-conflict/__tests__/base-conflict.ts new file mode 100644 index 00000000000000..05c74866abaebd --- /dev/null +++ b/playground/base-conflict/__tests__/base-conflict.ts @@ -0,0 +1,6 @@ +import { expect, test } from 'vitest' +import { page } from '~utils' + +test('absolute imports keep base prefix', async () => { + await expect.poll(() => page.textContent('.message')).toBe('absolute import') +}) diff --git a/playground/base-conflict/index.html b/playground/base-conflict/index.html new file mode 100644 index 00000000000000..9b5fb8c290bc5a --- /dev/null +++ b/playground/base-conflict/index.html @@ -0,0 +1,11 @@ + + + + + Base Conflict + + +
+ + + diff --git a/playground/base-conflict/package.json b/playground/base-conflict/package.json new file mode 100644 index 00000000000000..412ee3ce1f51cf --- /dev/null +++ b/playground/base-conflict/package.json @@ -0,0 +1,12 @@ +{ + "name": "@vitejs/test-base-conflict", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "debug": "node --inspect-brk ../../packages/vite/bin/vite", + "preview": "vite preview" + } +} diff --git a/playground/base-conflict/src/importee.ts b/playground/base-conflict/src/importee.ts new file mode 100644 index 00000000000000..1874734d97828b --- /dev/null +++ b/playground/base-conflict/src/importee.ts @@ -0,0 +1 @@ +export default 'absolute import' diff --git a/playground/base-conflict/src/main.ts b/playground/base-conflict/src/main.ts new file mode 100644 index 00000000000000..53cf31aeb4cf17 --- /dev/null +++ b/playground/base-conflict/src/main.ts @@ -0,0 +1,3 @@ +import message from 'absolute-importer' + +document.querySelector('.message')!.textContent = message diff --git a/playground/base-conflict/src/virtualModules.d.ts b/playground/base-conflict/src/virtualModules.d.ts new file mode 100644 index 00000000000000..ead02941e4bb80 --- /dev/null +++ b/playground/base-conflict/src/virtualModules.d.ts @@ -0,0 +1,4 @@ +declare module 'absolute-importer' { + const msg: string + export default msg +} diff --git a/playground/base-conflict/vite.config.ts b/playground/base-conflict/vite.config.ts new file mode 100644 index 00000000000000..178770db70cc09 --- /dev/null +++ b/playground/base-conflict/vite.config.ts @@ -0,0 +1,32 @@ +import { defineConfig, normalizePath } from 'vite' + +const rootPath = normalizePath(import.meta.dirname) +const absoluteRoot = rootPath.startsWith('/') ? rootPath : `/${rootPath}` +const [firstSegment] = absoluteRoot.split('/').filter(Boolean) +const base = firstSegment ? `/${firstSegment}/` : '/' + +const VIRTUAL_MODULE_ID = 'absolute-importer' +const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID + +const absoluteDepPath = `${rootPath}/src/importee.ts` +export default defineConfig({ + base, + plugins: [ + { + name: 'absolute-path-import', + resolveId(id) { + if (id === VIRTUAL_MODULE_ID) { + return RESOLVED_VIRTUAL_MODULE_ID + } + }, + load(id) { + if (id === RESOLVED_VIRTUAL_MODULE_ID) { + return ( + `import dep from ${JSON.stringify(absoluteDepPath)}\n` + + `export default dep` + ) + } + }, + }, + ], +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 998246c9488a9a..929f0c12929a50 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -595,6 +595,8 @@ importers: specifier: ^0.2.15 version: 0.2.15 + playground/base-conflict: {} + playground/build-old: {} playground/cli: {} From 8a3f01abcc5d08e0ccd7c0e7b5b14beab5883892 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Wed, 10 Dec 2025 19:22:47 +0900 Subject: [PATCH 4/5] test: fix test filename --- .../__tests__/{base-conflict.ts => base-conflict.spec.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename playground/base-conflict/__tests__/{base-conflict.ts => base-conflict.spec.ts} (100%) diff --git a/playground/base-conflict/__tests__/base-conflict.ts b/playground/base-conflict/__tests__/base-conflict.spec.ts similarity index 100% rename from playground/base-conflict/__tests__/base-conflict.ts rename to playground/base-conflict/__tests__/base-conflict.spec.ts From 42e257241796d3e2600bcd18ac08384868322fae Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Fri, 5 Dec 2025 20:09:20 +0900 Subject: [PATCH 5/5] fix: don't strip base from imports --- packages/vite/src/node/plugins/importAnalysis.ts | 2 -- packages/vite/src/node/plugins/worker.ts | 9 +++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/vite/src/node/plugins/importAnalysis.ts b/packages/vite/src/node/plugins/importAnalysis.ts index 89e9243423dfc8..a31c989c9d2a5a 100644 --- a/packages/vite/src/node/plugins/importAnalysis.ts +++ b/packages/vite/src/node/plugins/importAnalysis.ts @@ -326,8 +326,6 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin { pos: number, forceSkipImportAnalysis: boolean = false, ): Promise<[string, string | null]> => { - url = stripBase(url, base) - let importerFile = importer if ( diff --git a/packages/vite/src/node/plugins/worker.ts b/packages/vite/src/node/plugins/worker.ts index e311b93fd27168..5730a5b321c0e9 100644 --- a/packages/vite/src/node/plugins/worker.ts +++ b/packages/vite/src/node/plugins/worker.ts @@ -507,13 +507,14 @@ export function webWorkerPlugin(config: ResolvedConfig): Plugin { const workerType = workerFileMatch[1] as WorkerType let injectEnv = '' - const scriptPath = JSON.stringify( - path.posix.join(config.base, ENV_PUBLIC_PATH), - ) - if (workerType === 'classic') { + // base needs to be joined as the base is not injected to `importScripts` automatically + const scriptPath = JSON.stringify( + path.posix.join(config.base, ENV_PUBLIC_PATH), + ) injectEnv = `importScripts(${scriptPath})\n` } else if (workerType === 'module') { + const scriptPath = JSON.stringify(ENV_PUBLIC_PATH) injectEnv = `import ${scriptPath}\n` } else if (workerType === 'ignore') { if (isBuild) {