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) {
diff --git a/playground/base-conflict/__tests__/base-conflict.spec.ts b/playground/base-conflict/__tests__/base-conflict.spec.ts
new file mode 100644
index 00000000000000..05c74866abaebd
--- /dev/null
+++ b/playground/base-conflict/__tests__/base-conflict.spec.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: {}