diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts
index 2c45771c46e101..cf4c91e6bfc636 100644
--- a/packages/vite/src/node/plugins/resolve.ts
+++ b/packages/vite/src/node/plugins/resolve.ts
@@ -874,13 +874,15 @@ export async function tryOptimizedResolve(
const metadata = depsOptimizer.metadata
- const depInfo = optimizedDepInfoFromId(metadata, id)
- if (depInfo) {
- return depsOptimizer.getOptimizedDepId(depInfo)
+ if (!importer) {
+ // no importer. try our best to find an optimized dep
+ const depInfo = optimizedDepInfoFromId(metadata, id)
+ if (depInfo) {
+ return depsOptimizer.getOptimizedDepId(depInfo)
+ }
+ return
}
- if (!importer) return
-
// further check if id is imported by nested dependency
let resolvedSrc: string | undefined
diff --git a/playground/resolve-optimized-dup-deps/__tests__/resolve-optimized-dup-deps.spec.ts b/playground/resolve-optimized-dup-deps/__tests__/resolve-optimized-dup-deps.spec.ts
new file mode 100644
index 00000000000000..e2c1507ecdb2ff
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/__tests__/resolve-optimized-dup-deps.spec.ts
@@ -0,0 +1,7 @@
+import { expect, test } from 'vitest'
+import { page } from '~utils'
+
+test('resolve-optimized-dup-deps', async () => {
+ expect(await page.textContent('.a')).toBe('test-package-a:test-package-b-v2')
+ expect(await page.textContent('.b')).toBe('test-package-b-v1')
+})
diff --git a/playground/resolve-optimized-dup-deps/index.html b/playground/resolve-optimized-dup-deps/index.html
new file mode 100644
index 00000000000000..89b7bca36300e7
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/index.html
@@ -0,0 +1,17 @@
+
direct dependency A
+
+
+direct dependency B
+
+
+
diff --git a/playground/resolve-optimized-dup-deps/package-a/index.js b/playground/resolve-optimized-dup-deps/package-a/index.js
new file mode 100644
index 00000000000000..52c82187d5ee47
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/package-a/index.js
@@ -0,0 +1,6 @@
+import b from '@vitejs/test-resolve-optimized-dup-deps-package-b'
+
+// should get test-package-a:test-package-b-v2
+const result = 'test-package-a:' + b
+
+export default result
diff --git a/playground/resolve-optimized-dup-deps/package-a/package.json b/playground/resolve-optimized-dup-deps/package-a/package.json
new file mode 100644
index 00000000000000..a2c0067d1573cb
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/package-a/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@vitejs/test-resolve-optimized-dup-deps-package-a",
+ "private": true,
+ "version": "1.0.0",
+ "main": "index.js",
+ "dependencies": {
+ "@vitejs/test-resolve-optimized-dup-deps-package-b": "file:../package-b-v2"
+ }
+}
diff --git a/playground/resolve-optimized-dup-deps/package-b-v1/index.js b/playground/resolve-optimized-dup-deps/package-b-v1/index.js
new file mode 100644
index 00000000000000..7d6c1ef0a992f1
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/package-b-v1/index.js
@@ -0,0 +1,3 @@
+// test-package-b-v1 is install and imported by user
+// it is written in cjs and should be optimized
+module.exports = 'test-package-b-v1'
diff --git a/playground/resolve-optimized-dup-deps/package-b-v1/package.json b/playground/resolve-optimized-dup-deps/package-b-v1/package.json
new file mode 100644
index 00000000000000..68b1c74f57f8e0
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/package-b-v1/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "@vitejs/test-resolve-optimized-dup-deps-package-b",
+ "private": true,
+ "version": "1.0.0",
+ "main": "index.js"
+}
diff --git a/playground/resolve-optimized-dup-deps/package-b-v2/index.js b/playground/resolve-optimized-dup-deps/package-b-v2/index.js
new file mode 100644
index 00000000000000..204404e745db09
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/package-b-v2/index.js
@@ -0,0 +1,3 @@
+// test-package-b-v2 is install and imported by test-package-a
+// it is written in esm. it is not optimized
+export default 'test-package-b-v2'
diff --git a/playground/resolve-optimized-dup-deps/package-b-v2/package.json b/playground/resolve-optimized-dup-deps/package-b-v2/package.json
new file mode 100644
index 00000000000000..ba9c84ea4538d6
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/package-b-v2/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "@vitejs/test-resolve-optimized-dup-deps-package-b",
+ "private": true,
+ "version": "2.0.0",
+ "main": "index.js"
+}
diff --git a/playground/resolve-optimized-dup-deps/package.json b/playground/resolve-optimized-dup-deps/package.json
new file mode 100644
index 00000000000000..71267db3985ddd
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "@vitejs/test-resolve-optimized-dup-deps",
+ "private": true,
+ "version": "0.0.0",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "debug": "node --inspect-brk ../../packages/vite/bin/vite",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@vitejs/test-resolve-optimized-dup-deps-package-a": "file:./package-a",
+ "@vitejs/test-resolve-optimized-dup-deps-package-b": "file:./package-b-v1"
+ }
+}
diff --git a/playground/resolve-optimized-dup-deps/vite.config.js b/playground/resolve-optimized-dup-deps/vite.config.js
new file mode 100644
index 00000000000000..2d6290f12b9098
--- /dev/null
+++ b/playground/resolve-optimized-dup-deps/vite.config.js
@@ -0,0 +1,8 @@
+/**
+ * @type {import('vite').UserConfig}
+ */
+module.exports = {
+ optimizeDeps: {
+ exclude: ['@vitejs/test-resolve-optimized-dup-deps-package-a'],
+ },
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 589ad1ed077a84..a25099334d3e4a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -829,6 +829,26 @@ importers:
playground/resolve-linked:
specifiers: {}
+ playground/resolve-optimized-dup-deps:
+ specifiers:
+ '@vitejs/test-resolve-optimized-dup-deps-package-a': file:./package-a
+ '@vitejs/test-resolve-optimized-dup-deps-package-b': file:./package-b-v1
+ dependencies:
+ '@vitejs/test-resolve-optimized-dup-deps-package-a': file:playground/resolve-optimized-dup-deps/package-a
+ '@vitejs/test-resolve-optimized-dup-deps-package-b': file:playground/resolve-optimized-dup-deps/package-b-v1
+
+ playground/resolve-optimized-dup-deps/package-a:
+ specifiers:
+ '@vitejs/test-resolve-optimized-dup-deps-package-b': file:../package-b-v2
+ dependencies:
+ '@vitejs/test-resolve-optimized-dup-deps-package-b': file:playground/resolve-optimized-dup-deps/package-b-v2
+
+ playground/resolve-optimized-dup-deps/package-b-v1:
+ specifiers: {}
+
+ playground/resolve-optimized-dup-deps/package-b-v2:
+ specifiers: {}
+
playground/resolve/browser-field:
specifiers: {}
@@ -8727,6 +8747,26 @@ packages:
dep-a: file:playground/preload/dep-a
dev: true
+ file:playground/resolve-optimized-dup-deps/package-a:
+ resolution: {directory: playground/resolve-optimized-dup-deps/package-a, type: directory}
+ name: '@vitejs/test-resolve-optimized-dup-deps-package-a'
+ version: 1.0.0
+ dependencies:
+ '@vitejs/test-resolve-optimized-dup-deps-package-b': file:playground/resolve-optimized-dup-deps/package-b-v2
+ dev: false
+
+ file:playground/resolve-optimized-dup-deps/package-b-v1:
+ resolution: {directory: playground/resolve-optimized-dup-deps/package-b-v1, type: directory}
+ name: '@vitejs/test-resolve-optimized-dup-deps-package-b'
+ version: 1.0.0
+ dev: false
+
+ file:playground/resolve-optimized-dup-deps/package-b-v2:
+ resolution: {directory: playground/resolve-optimized-dup-deps/package-b-v2, type: directory}
+ name: '@vitejs/test-resolve-optimized-dup-deps-package-b'
+ version: 2.0.0
+ dev: false
+
file:playground/ssr-deps/css-lib:
resolution: {directory: playground/ssr-deps/css-lib, type: directory}
name: '@vitejs/test-css-lib'