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'