From 82ad4bfd5c90f081b544d43a5ee2932036129e5f Mon Sep 17 00:00:00 2001 From: csr632 <632882184@qq.com> Date: Tue, 13 Dec 2022 02:35:02 +0800 Subject: [PATCH 1/9] fix: wrongly resolve to optimized doppelganger (#11290) --- packages/vite/src/node/plugins/resolve.ts | 12 +++--- .../resolve-optimized-dup-deps.spec.ts | 7 ++++ .../resolve-optimized-dup-deps/index.html | 17 ++++++++ .../package-a/index.js | 6 +++ .../package-a/package.json | 9 +++++ .../package-b-v1/index.js | 3 ++ .../package-b-v1/package.json | 6 +++ .../package-b-v2/index.js | 3 ++ .../package-b-v2/package.json | 6 +++ .../resolve-optimized-dup-deps/package.json | 15 +++++++ .../resolve-optimized-dup-deps/vite.config.js | 8 ++++ pnpm-lock.yaml | 40 +++++++++++++++++++ 12 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 playground/resolve-optimized-dup-deps/__tests__/resolve-optimized-dup-deps.spec.ts create mode 100644 playground/resolve-optimized-dup-deps/index.html create mode 100644 playground/resolve-optimized-dup-deps/package-a/index.js create mode 100644 playground/resolve-optimized-dup-deps/package-a/package.json create mode 100644 playground/resolve-optimized-dup-deps/package-b-v1/index.js create mode 100644 playground/resolve-optimized-dup-deps/package-b-v1/package.json create mode 100644 playground/resolve-optimized-dup-deps/package-b-v2/index.js create mode 100644 playground/resolve-optimized-dup-deps/package-b-v2/package.json create mode 100644 playground/resolve-optimized-dup-deps/package.json create mode 100644 playground/resolve-optimized-dup-deps/vite.config.js diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 81480c9e67dbf5..404b012f58983f 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -888,13 +888,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 4c4607a617bd75..0ec985053acfbe 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: {}
 
@@ -8780,6 +8800,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'

From d5a2d78c91b0da2d5eb27126d67c02794b011d4a Mon Sep 17 00:00:00 2001
From: csr632 <632882184@qq.com>
Date: Sun, 18 Dec 2022 15:04:50 +0800
Subject: [PATCH 2/9] test: add test that fail to resolve to optimized dep

---
 .../__tests__/resolve-optimized.spec.ts       | 19 ++++++++
 playground/resolve-optimized/index.html       | 46 +++++++++++++++++++
 .../resolve-optimized/package-a/index.main.js |  3 ++
 .../package-a/index.module.js                 |  6 +++
 .../resolve-optimized/package-a/package.json  |  8 ++++
 .../package-b/index.module.js                 |  5 ++
 .../resolve-optimized/package-b/package.json  | 12 +++++
 .../package-custom-condition/index.custom.js  |  6 +++
 .../package-custom-condition/index.js         |  3 ++
 .../package-custom-condition/package.json     | 13 ++++++
 .../package-custom-main-field/index.custom.js |  6 +++
 .../package-custom-main-field/index.js        |  3 ++
 .../package-custom-main-field/package.json    |  7 +++
 playground/resolve-optimized/package.json     | 17 +++++++
 playground/resolve-optimized/vite.config.js   | 13 ++++++
 15 files changed, 167 insertions(+)
 create mode 100644 playground/resolve-optimized/__tests__/resolve-optimized.spec.ts
 create mode 100644 playground/resolve-optimized/index.html
 create mode 100644 playground/resolve-optimized/package-a/index.main.js
 create mode 100644 playground/resolve-optimized/package-a/index.module.js
 create mode 100644 playground/resolve-optimized/package-a/package.json
 create mode 100644 playground/resolve-optimized/package-b/index.module.js
 create mode 100644 playground/resolve-optimized/package-b/package.json
 create mode 100644 playground/resolve-optimized/package-custom-condition/index.custom.js
 create mode 100644 playground/resolve-optimized/package-custom-condition/index.js
 create mode 100644 playground/resolve-optimized/package-custom-condition/package.json
 create mode 100644 playground/resolve-optimized/package-custom-main-field/index.custom.js
 create mode 100644 playground/resolve-optimized/package-custom-main-field/index.js
 create mode 100644 playground/resolve-optimized/package-custom-main-field/package.json
 create mode 100644 playground/resolve-optimized/package.json
 create mode 100644 playground/resolve-optimized/vite.config.js

diff --git a/playground/resolve-optimized/__tests__/resolve-optimized.spec.ts b/playground/resolve-optimized/__tests__/resolve-optimized.spec.ts
new file mode 100644
index 00000000000000..628f91f3a9b802
--- /dev/null
+++ b/playground/resolve-optimized/__tests__/resolve-optimized.spec.ts
@@ -0,0 +1,19 @@
+import { expect, test } from 'vitest'
+import { page } from '~utils'
+
+test('resolve-optimized', async () => {
+  expect(await page.textContent('.a')).toBe('package-a-module')
+  expect(await page.textContent('.b')).toBe(
+    'package-b-module:package-a-module:package-custom-main-field:package-custom-condition',
+  )
+  expect(await page.textContent('.custom-main-field')).toBe(
+    'package-custom-main-field',
+  )
+  expect(await page.textContent('.custom-condition')).toBe(
+    'package-custom-condition',
+  )
+
+  expect(await page.textContent('.a-count')).toBe('success')
+  expect(await page.textContent('.custom-main-field-count')).toBe('success')
+  expect(await page.textContent('.custom-condition-count')).toBe('success')
+})
diff --git a/playground/resolve-optimized/index.html b/playground/resolve-optimized/index.html
new file mode 100644
index 00000000000000..dd4544ca828f9b
--- /dev/null
+++ b/playground/resolve-optimized/index.html
@@ -0,0 +1,46 @@
+

direct dependency A

+

+

+
+

direct dependency B

+

+
+

direct dependency custom-main-field

+

+

+
+

direct dependency custom-condition

+

+

+
+
diff --git a/playground/resolve-optimized/package-a/index.main.js b/playground/resolve-optimized/package-a/index.main.js
new file mode 100644
index 00000000000000..064a081489e136
--- /dev/null
+++ b/playground/resolve-optimized/package-a/index.main.js
@@ -0,0 +1,3 @@
+export default 'package-a-main'
+
+throw new Error('should resolve to package-a/index.module.js instead of this')
diff --git a/playground/resolve-optimized/package-a/index.module.js b/playground/resolve-optimized/package-a/index.module.js
new file mode 100644
index 00000000000000..53c7756645146c
--- /dev/null
+++ b/playground/resolve-optimized/package-a/index.module.js
@@ -0,0 +1,6 @@
+const key = 'package-a-module'
+
+export default key
+
+globalThis[key] ||= 0
+globalThis[key]++
diff --git a/playground/resolve-optimized/package-a/package.json b/playground/resolve-optimized/package-a/package.json
new file mode 100644
index 00000000000000..acb5911de21a08
--- /dev/null
+++ b/playground/resolve-optimized/package-a/package.json
@@ -0,0 +1,8 @@
+{
+  "name": "@vitejs/test-resolve-optimized-package-a",
+  "private": true,
+  "version": "1.0.0",
+  "main": "index.main.js",
+  "module": "index.module.js",
+  "dependencies": {}
+}
diff --git a/playground/resolve-optimized/package-b/index.module.js b/playground/resolve-optimized/package-b/index.module.js
new file mode 100644
index 00000000000000..64bbc86a2bb605
--- /dev/null
+++ b/playground/resolve-optimized/package-b/index.module.js
@@ -0,0 +1,5 @@
+import a from '@vitejs/test-resolve-optimized-package-a'
+import customMain from '@vitejs/test-resolve-optimized-package-custom-main-field'
+import customCondition from '@vitejs/test-resolve-optimized-package-custom-condition'
+
+export default `package-b-module:${a}:${customMain}:${customCondition}`
diff --git a/playground/resolve-optimized/package-b/package.json b/playground/resolve-optimized/package-b/package.json
new file mode 100644
index 00000000000000..1636a87a1b9fa6
--- /dev/null
+++ b/playground/resolve-optimized/package-b/package.json
@@ -0,0 +1,12 @@
+{
+  "name": "@vitejs/test-resolve-optimized-package-b",
+  "private": true,
+  "version": "1.0.0",
+  "module": "index.module.js",
+  "dependencies": {},
+  "peerDependencies": {
+    "@vitejs/test-resolve-optimized-package-a": "*",
+    "@vitejs/test-resolve-optimized-package-custom-condition": "*",
+    "@vitejs/test-resolve-optimized-package-custom-main-field": "*"
+  }
+}
diff --git a/playground/resolve-optimized/package-custom-condition/index.custom.js b/playground/resolve-optimized/package-custom-condition/index.custom.js
new file mode 100644
index 00000000000000..4e21f0120f24fe
--- /dev/null
+++ b/playground/resolve-optimized/package-custom-condition/index.custom.js
@@ -0,0 +1,6 @@
+const key = 'package-custom-condition'
+
+export default key
+
+globalThis[key] ||= 0
+globalThis[key]++
diff --git a/playground/resolve-optimized/package-custom-condition/index.js b/playground/resolve-optimized/package-custom-condition/index.js
new file mode 100644
index 00000000000000..2acbd887fce5ff
--- /dev/null
+++ b/playground/resolve-optimized/package-custom-condition/index.js
@@ -0,0 +1,3 @@
+export default '[fail]'
+
+throw new Error('should resolve to custom condition instead of this')
diff --git a/playground/resolve-optimized/package-custom-condition/package.json b/playground/resolve-optimized/package-custom-condition/package.json
new file mode 100644
index 00000000000000..5bb2f63cdb5be6
--- /dev/null
+++ b/playground/resolve-optimized/package-custom-condition/package.json
@@ -0,0 +1,13 @@
+{
+  "name": "@vitejs/test-resolve-optimized-package-custom-condition",
+  "private": true,
+  "version": "1.0.0",
+  "main": "index.js",
+  "exports": {
+    ".": {
+      "custom": "./index.custom.js",
+      "import": "./index.js",
+      "require": "./index.js"
+    }
+  }
+}
diff --git a/playground/resolve-optimized/package-custom-main-field/index.custom.js b/playground/resolve-optimized/package-custom-main-field/index.custom.js
new file mode 100644
index 00000000000000..2ea5db9ba8aae3
--- /dev/null
+++ b/playground/resolve-optimized/package-custom-main-field/index.custom.js
@@ -0,0 +1,6 @@
+const key = 'package-custom-main-field'
+
+export default key
+
+globalThis[key] ||= 0
+globalThis[key]++
diff --git a/playground/resolve-optimized/package-custom-main-field/index.js b/playground/resolve-optimized/package-custom-main-field/index.js
new file mode 100644
index 00000000000000..4dd83909cacc48
--- /dev/null
+++ b/playground/resolve-optimized/package-custom-main-field/index.js
@@ -0,0 +1,3 @@
+export default '[fail]'
+
+throw new Error('should resolve to custom main field instead of this')
diff --git a/playground/resolve-optimized/package-custom-main-field/package.json b/playground/resolve-optimized/package-custom-main-field/package.json
new file mode 100644
index 00000000000000..d0d973ccfaf5b1
--- /dev/null
+++ b/playground/resolve-optimized/package-custom-main-field/package.json
@@ -0,0 +1,7 @@
+{
+  "name": "@vitejs/test-resolve-optimized-package-custom-main-field",
+  "private": true,
+  "version": "1.0.0",
+  "main": "index.js",
+  "custom": "index.custom.js"
+}
diff --git a/playground/resolve-optimized/package.json b/playground/resolve-optimized/package.json
new file mode 100644
index 00000000000000..6494761b54c4d7
--- /dev/null
+++ b/playground/resolve-optimized/package.json
@@ -0,0 +1,17 @@
+{
+  "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-package-a": "file:./package-a",
+    "@vitejs/test-resolve-optimized-package-b": "file:./package-b",
+    "@vitejs/test-resolve-optimized-package-custom-condition": "file:./package-custom-condition",
+    "@vitejs/test-resolve-optimized-package-custom-main-field": "file:./package-custom-main-field"
+  }
+}
diff --git a/playground/resolve-optimized/vite.config.js b/playground/resolve-optimized/vite.config.js
new file mode 100644
index 00000000000000..93581bb0844b19
--- /dev/null
+++ b/playground/resolve-optimized/vite.config.js
@@ -0,0 +1,13 @@
+/**
+ * @type {import('vite').UserConfig}
+ */
+module.exports = {
+  optimizeDeps: {
+    exclude: ['@vitejs/test-resolve-optimized-package-b'],
+  },
+  resolve: {
+    // test if tryOptimizedResolve respect resolve options
+    mainFields: ['custom', 'module'],
+    conditions: ['custom'],
+  },
+}

From 7115fbfdd7e8816d4e364eb49e349cdc9ae0f5e6 Mon Sep 17 00:00:00 2001
From: csr632 <632882184@qq.com>
Date: Sun, 18 Dec 2022 15:11:14 +0800
Subject: [PATCH 3/9] fix: unoptimized package can resolve to optimized deps

---
 packages/vite/src/node/plugins/index.ts    | 33 +++++++++++---------
 packages/vite/src/node/plugins/preAlias.ts | 10 ++++--
 packages/vite/src/node/plugins/resolve.ts  | 36 +++++++++++++++++-----
 3 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/packages/vite/src/node/plugins/index.ts b/packages/vite/src/node/plugins/index.ts
index 1dbd8bf90b95fc..df0cd1a35b6402 100644
--- a/packages/vite/src/node/plugins/index.ts
+++ b/packages/vite/src/node/plugins/index.ts
@@ -6,6 +6,7 @@ import { getDepsOptimizer } from '../optimizer'
 import { shouldExternalizeForSSR } from '../ssr/ssrExternal'
 import { jsonPlugin } from './json'
 import { resolvePlugin } from './resolve'
+import type { InternalResolveOptions } from './resolve'
 import { optimizedDepsBuildPlugin, optimizedDepsPlugin } from './optimizedDeps'
 import { esbuildPlugin } from './esbuild'
 import { importAnalysisPlugin } from './importAnalysis'
@@ -38,10 +39,25 @@ export async function resolvePlugins(
     : { pre: [], post: [] }
   const { modulePreload } = config.build
 
+  const resolveOptions: InternalResolveOptions = {
+    ...config.resolve,
+    root: config.root,
+    isProduction: config.isProduction,
+    isBuild,
+    packageCache: config.packageCache,
+    ssrConfig: config.ssr,
+    asSrc: true,
+    getDepsOptimizer: (ssr: boolean) => getDepsOptimizer(config, ssr),
+    shouldExternalize:
+      isBuild && config.build.ssr && config.ssr?.format !== 'cjs'
+        ? (id) => shouldExternalizeForSSR(id, config)
+        : undefined,
+  }
+
   return [
     isWatch ? ensureWatchPlugin() : null,
     isBuild ? metadataPlugin() : null,
-    preAliasPlugin(config),
+    preAliasPlugin(config, resolveOptions),
     aliasPlugin({ entries: config.resolve.alias }),
     ...prePlugins,
     modulePreload === true ||
@@ -56,20 +72,7 @@ export async function resolvePlugins(
             : optimizedDepsPlugin(config),
         ]
       : []),
-    resolvePlugin({
-      ...config.resolve,
-      root: config.root,
-      isProduction: config.isProduction,
-      isBuild,
-      packageCache: config.packageCache,
-      ssrConfig: config.ssr,
-      asSrc: true,
-      getDepsOptimizer: (ssr: boolean) => getDepsOptimizer(config, ssr),
-      shouldExternalize:
-        isBuild && config.build.ssr && config.ssr?.format !== 'cjs'
-          ? (id) => shouldExternalizeForSSR(id, config)
-          : undefined,
-    }),
+    resolvePlugin(resolveOptions),
     htmlInlineProxyPlugin(config),
     cssPlugin(config),
     config.esbuild !== false ? esbuildPlugin(config.esbuild) : null,
diff --git a/packages/vite/src/node/plugins/preAlias.ts b/packages/vite/src/node/plugins/preAlias.ts
index 2b285723d1d80a..93482990efa1fa 100644
--- a/packages/vite/src/node/plugins/preAlias.ts
+++ b/packages/vite/src/node/plugins/preAlias.ts
@@ -16,11 +16,15 @@ import {
 } from '../utils'
 import { getDepsOptimizer } from '../optimizer'
 import { tryOptimizedResolve } from './resolve'
+import type { InternalResolveOptions } from './resolve'
 
 /**
  * A plugin to avoid an aliased AND optimized dep from being aliased in src
  */
-export function preAliasPlugin(config: ResolvedConfig): Plugin {
+export function preAliasPlugin(
+  config: ResolvedConfig,
+  resolveOptions: InternalResolveOptions,
+): Plugin {
   const findPatterns = getAliasPatterns(config.resolve.alias)
   const isConfiguredAsExternal = createIsConfiguredAsSsrExternal(config)
   const isBuild = config.command === 'build'
@@ -39,9 +43,11 @@ export function preAliasPlugin(config: ResolvedConfig): Plugin {
       ) {
         if (findPatterns.find((pattern) => matches(pattern, id))) {
           const optimizedId = await tryOptimizedResolve(
-            depsOptimizer,
             id,
             importer,
+            resolveOptions,
+            depsOptimizer,
+            ssr,
           )
           if (optimizedId) {
             return optimizedId // aliased dep already optimized
diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts
index 404b012f58983f..b1d7cc7d9d6ff8 100644
--- a/packages/vite/src/node/plugins/resolve.ts
+++ b/packages/vite/src/node/plugins/resolve.ts
@@ -35,7 +35,6 @@ import {
   lookupFile,
   nestedResolveFrom,
   normalizePath,
-  resolveFrom,
   slash,
 } from '../utils'
 import { optimizedDepInfoFromFile, optimizedDepInfoFromId } from '../optimizer'
@@ -309,7 +308,13 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin {
           asSrc &&
           depsOptimizer &&
           !options.scan &&
-          (res = await tryOptimizedResolve(depsOptimizer, id, importer))
+          (res = await tryOptimizedResolve(
+            id,
+            importer,
+            options,
+            depsOptimizer,
+            ssr,
+          ))
         ) {
           return res
         }
@@ -802,7 +807,7 @@ export function tryNodeResolve(
   if (
     !options.ssrOptimizeCheck &&
     (!resolved.includes('node_modules') || // linked
-      !depsOptimizer || // resolving before listening to the server
+      !depsOptimizer || // resolving before listening to the server, or called by tryOptimizedResolve
       options.scan) // initial esbuild scan phase
   ) {
     return { id: resolved }
@@ -876,9 +881,11 @@ export function tryNodeResolve(
 }
 
 export async function tryOptimizedResolve(
-  depsOptimizer: DepsOptimizer,
   id: string,
-  importer?: string,
+  importer: string | null | undefined,
+  resolveOptions: InternalResolveOptions,
+  depsOptimizer: DepsOptimizer,
+  ssr: boolean,
 ): Promise {
   // TODO: we need to wait until scanning is done here as this function
   // is used in the preAliasPlugin to decide if an aliased dep is optimized,
@@ -913,8 +920,23 @@ export async function tryOptimizedResolve(
     // lazily initialize resolvedSrc
     if (resolvedSrc == null) {
       try {
-        // this may throw errors if unable to resolve, e.g. aliased id
-        resolvedSrc = normalizePath(resolveFrom(id, path.dirname(importer)))
+        const { target: ssrTarget } = resolveOptions.ssrConfig ?? {}
+        const targetWeb = !ssr || ssrTarget === 'webworker'
+        const resolved = tryNodeResolve(
+          id,
+          importer,
+          resolveOptions,
+          targetWeb,
+          undefined,
+          ssr,
+          false,
+        )
+        if (resolved?.id) {
+          resolvedSrc = normalizePath(resolved.id)
+        } else {
+          // no resolvedSrc, no need to continue
+          break
+        }
       } catch {
         // this is best-effort only so swallow errors
         break

From 83e328ebd360c2be2d85e0db47063aaa92f9e531 Mon Sep 17 00:00:00 2001
From: csr632 <632882184@qq.com>
Date: Sun, 18 Dec 2022 21:49:11 +0800
Subject: [PATCH 4/9] update pnpm-lock

---
 pnpm-lock.yaml | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0ec985053acfbe..c9faf13add215f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -829,6 +829,18 @@ importers:
   playground/resolve-linked:
     specifiers: {}
 
+  playground/resolve-optimized:
+    specifiers:
+      '@vitejs/test-resolve-optimized-package-a': file:./package-a
+      '@vitejs/test-resolve-optimized-package-b': file:./package-b
+      '@vitejs/test-resolve-optimized-package-custom-condition': file:./package-custom-condition
+      '@vitejs/test-resolve-optimized-package-custom-main-field': file:./package-custom-main-field
+    dependencies:
+      '@vitejs/test-resolve-optimized-package-a': file:playground/resolve-optimized/package-a
+      '@vitejs/test-resolve-optimized-package-b': file:playground/resolve-optimized/package-b_j3czbr56p6y2ktoozljpzmhxu4
+      '@vitejs/test-resolve-optimized-package-custom-condition': file:playground/resolve-optimized/package-custom-condition
+      '@vitejs/test-resolve-optimized-package-custom-main-field': file:playground/resolve-optimized/package-custom-main-field
+
   playground/resolve-optimized-dup-deps:
     specifiers:
       '@vitejs/test-resolve-optimized-dup-deps-package-a': file:./package-a
@@ -849,6 +861,18 @@ importers:
   playground/resolve-optimized-dup-deps/package-b-v2:
     specifiers: {}
 
+  playground/resolve-optimized/package-a:
+    specifiers: {}
+
+  playground/resolve-optimized/package-b:
+    specifiers: {}
+
+  playground/resolve-optimized/package-custom-condition:
+    specifiers: {}
+
+  playground/resolve-optimized/package-custom-main-field:
+    specifiers: {}
+
   playground/resolve/browser-field:
     specifiers: {}
 
@@ -8820,6 +8844,39 @@ packages:
     version: 2.0.0
     dev: false
 
+  file:playground/resolve-optimized/package-a:
+    resolution: {directory: playground/resolve-optimized/package-a, type: directory}
+    name: '@vitejs/test-resolve-optimized-package-a'
+    version: 1.0.0
+    dev: false
+
+  file:playground/resolve-optimized/package-b_j3czbr56p6y2ktoozljpzmhxu4:
+    resolution: {directory: playground/resolve-optimized/package-b, type: directory}
+    id: file:playground/resolve-optimized/package-b
+    name: '@vitejs/test-resolve-optimized-package-b'
+    version: 1.0.0
+    peerDependencies:
+      '@vitejs/test-resolve-optimized-package-a': '*'
+      '@vitejs/test-resolve-optimized-package-custom-condition': '*'
+      '@vitejs/test-resolve-optimized-package-custom-main-field': '*'
+    dependencies:
+      '@vitejs/test-resolve-optimized-package-a': file:playground/resolve-optimized/package-a
+      '@vitejs/test-resolve-optimized-package-custom-condition': file:playground/resolve-optimized/package-custom-condition
+      '@vitejs/test-resolve-optimized-package-custom-main-field': file:playground/resolve-optimized/package-custom-main-field
+    dev: false
+
+  file:playground/resolve-optimized/package-custom-condition:
+    resolution: {directory: playground/resolve-optimized/package-custom-condition, type: directory}
+    name: '@vitejs/test-resolve-optimized-package-custom-condition'
+    version: 1.0.0
+    dev: false
+
+  file:playground/resolve-optimized/package-custom-main-field:
+    resolution: {directory: playground/resolve-optimized/package-custom-main-field, type: directory}
+    name: '@vitejs/test-resolve-optimized-package-custom-main-field'
+    version: 1.0.0
+    dev: false
+
   file:playground/ssr-deps/css-lib:
     resolution: {directory: playground/ssr-deps/css-lib, type: directory}
     name: '@vitejs/test-css-lib'

From 9e77ae14043438e7a96194c9a9768d8417cf0e07 Mon Sep 17 00:00:00 2001
From: csr632 <632882184@qq.com>
Date: Sun, 18 Dec 2022 23:51:50 +0800
Subject: [PATCH 5/9] split tryNodeResolve into tryNodeResolveCore

---
 packages/vite/src/node/plugins/resolve.ts | 92 ++++++++++++++++++-----
 1 file changed, 72 insertions(+), 20 deletions(-)

diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts
index b1d7cc7d9d6ff8..b1004559dac0e1 100644
--- a/packages/vite/src/node/plugins/resolve.ts
+++ b/packages/vite/src/node/plugins/resolve.ts
@@ -604,26 +604,28 @@ export type InternalResolveOptionsWithOverrideConditions =
 
 export const idToPkgMap = new Map()
 
-export function tryNodeResolve(
+export type TryNodeResolveCoreResult =
+  | {
+      resultType: 'success'
+      resolved: string
+      // nestedPath: string
+      pkg: PackageData
+      pkgId: string
+      nearestPkg: PackageData
+      isDeepImport: boolean
+    }
+  | { resultType: 'optional-peer-dep'; resolved: string }
+  | { resultType: 'fail' }
+
+export function tryNodeResolveCore(
   id: string,
   importer: string | null | undefined,
   options: InternalResolveOptionsWithOverrideConditions,
   targetWeb: boolean,
-  depsOptimizer?: DepsOptimizer,
-  ssr?: boolean,
-  externalize?: boolean,
-  allowLinkedExternal: boolean = true,
-): PartialResolvedId | undefined {
-  const { root, dedupe, isBuild, preserveSymlinks, packageCache } = options
+): TryNodeResolveCoreResult {
+  const { root, dedupe, preserveSymlinks, packageCache } = options
 
-  ssr ??= false
-
-  // split id by last '>' for nested selected packages, for example:
-  // 'foo > bar > baz' => 'foo > bar' & 'baz'
-  // 'foo'             => ''          & 'foo'
-  const lastArrowIndex = id.lastIndexOf('>')
-  const nestedRoot = id.substring(0, lastArrowIndex).trim()
-  const nestedPath = id.substring(lastArrowIndex + 1).trim()
+  const { nestedRoot, nestedPath } = parseNestedId(id)
 
   const possiblePkgIds: string[] = []
   for (let prevSlashIndex = -1; ; ) {
@@ -722,12 +724,13 @@ export function tryNodeResolve(
           mainPkg.peerDependenciesMeta?.[nestedPath]?.optional
         ) {
           return {
-            id: `${optionalPeerDepId}:${nestedPath}:${mainPkg.name}`,
+            resultType: 'optional-peer-dep',
+            resolved: `${optionalPeerDepId}:${nestedPath}:${mainPkg.name}`,
           }
         }
       }
     }
-    return
+    return { resultType: 'fail' }
   }
 
   let resolveId = resolvePackageEntry
@@ -755,9 +758,48 @@ export function tryNodeResolve(
     })
   }
   if (!resolved) {
-    return
+    return { resultType: 'fail' }
   }
 
+  // link id to pkg for browser field mapping check
+  idToPkgMap.set(resolved, pkg)
+
+  return {
+    resultType: 'success',
+    resolved,
+    pkg,
+    pkgId,
+    nearestPkg,
+    isDeepImport,
+  }
+}
+
+export function tryNodeResolve(
+  id: string,
+  importer: string | null | undefined,
+  options: InternalResolveOptionsWithOverrideConditions,
+  targetWeb: boolean,
+  depsOptimizer?: DepsOptimizer,
+  ssr?: boolean,
+  externalize?: boolean,
+  allowLinkedExternal: boolean = true,
+): PartialResolvedId | undefined {
+  const coreResult = tryNodeResolveCore(id, importer, options, targetWeb)
+  if (coreResult.resultType === 'fail') return
+  if (coreResult.resultType === 'optional-peer-dep')
+    return {
+      id: coreResult.resolved,
+    }
+  if (coreResult.resultType !== 'success')
+    throw new Error('assertion error: unexpected coreResult.resultType')
+
+  const { pkg, pkgId, nearestPkg, isDeepImport } = coreResult
+  let { resolved } = coreResult
+  // const {} = pkg
+  const { isBuild } = options
+  ssr ??= false
+  const { nestedPath } = parseNestedId(id)
+
   const processResult = (resolved: PartialResolvedId) => {
     if (!externalize) {
       return resolved
@@ -789,8 +831,6 @@ export function tryNodeResolve(
     return { ...resolved, id: resolvedId, external: true }
   }
 
-  // link id to pkg for browser field mapping check
-  idToPkgMap.set(resolved, pkg)
   if ((isBuild && !depsOptimizer) || externalize) {
     // Resolve package side effects for build so that rollup can better
     // perform tree-shaking
@@ -880,6 +920,18 @@ export function tryNodeResolve(
   }
 }
 
+/**
+ * split id by last '>' for nested selected packages, for example:
+ * 'foo > bar > baz' => 'foo > bar' & 'baz'
+ * 'foo'             => ''          & 'foo'
+ */
+function parseNestedId(id: string) {
+  const lastArrowIndex = id.lastIndexOf('>')
+  const nestedRoot = id.substring(0, lastArrowIndex).trim()
+  const nestedPath = id.substring(lastArrowIndex + 1).trim()
+  return { nestedRoot, nestedPath }
+}
+
 export async function tryOptimizedResolve(
   id: string,
   importer: string | null | undefined,

From 7944bcb1d2a655d45aba411377048fb641a0431e Mon Sep 17 00:00:00 2001
From: csr632 <632882184@qq.com>
Date: Sun, 8 Jan 2023 22:28:22 +0800
Subject: [PATCH 6/9] tryOptimizedResolve use tryNodeResolveCore

---
 packages/vite/src/node/plugins/preAlias.ts |  6 +++++-
 packages/vite/src/node/plugins/resolve.ts  | 21 +++++++--------------
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/packages/vite/src/node/plugins/preAlias.ts b/packages/vite/src/node/plugins/preAlias.ts
index 93482990efa1fa..92dae6a2f84990 100644
--- a/packages/vite/src/node/plugins/preAlias.ts
+++ b/packages/vite/src/node/plugins/preAlias.ts
@@ -28,6 +28,9 @@ export function preAliasPlugin(
   const findPatterns = getAliasPatterns(config.resolve.alias)
   const isConfiguredAsExternal = createIsConfiguredAsSsrExternal(config)
   const isBuild = config.command === 'build'
+  const { ssrConfig } = resolveOptions
+  const { target: ssrTarget } = ssrConfig ?? {}
+
   return {
     name: 'vite:pre-alias',
     async resolveId(id, importer, options) {
@@ -42,12 +45,13 @@ export function preAliasPlugin(
         id !== '@vite/env'
       ) {
         if (findPatterns.find((pattern) => matches(pattern, id))) {
+          const targetWeb = !ssr || ssrTarget === 'webworker'
           const optimizedId = await tryOptimizedResolve(
             id,
             importer,
             resolveOptions,
+            targetWeb,
             depsOptimizer,
-            ssr,
           )
           if (optimizedId) {
             return optimizedId // aliased dep already optimized
diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts
index b1004559dac0e1..74eebd880266f2 100644
--- a/packages/vite/src/node/plugins/resolve.ts
+++ b/packages/vite/src/node/plugins/resolve.ts
@@ -312,8 +312,8 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin {
             id,
             importer,
             options,
+            targetWeb,
             depsOptimizer,
-            ssr,
           ))
         ) {
           return res
@@ -608,7 +608,6 @@ export type TryNodeResolveCoreResult =
   | {
       resultType: 'success'
       resolved: string
-      // nestedPath: string
       pkg: PackageData
       pkgId: string
       nearestPkg: PackageData
@@ -795,7 +794,6 @@ export function tryNodeResolve(
 
   const { pkg, pkgId, nearestPkg, isDeepImport } = coreResult
   let { resolved } = coreResult
-  // const {} = pkg
   const { isBuild } = options
   ssr ??= false
   const { nestedPath } = parseNestedId(id)
@@ -847,7 +845,7 @@ export function tryNodeResolve(
   if (
     !options.ssrOptimizeCheck &&
     (!resolved.includes('node_modules') || // linked
-      !depsOptimizer || // resolving before listening to the server, or called by tryOptimizedResolve
+      !depsOptimizer || // resolving before listening to the server
       options.scan) // initial esbuild scan phase
   ) {
     return { id: resolved }
@@ -936,8 +934,8 @@ export async function tryOptimizedResolve(
   id: string,
   importer: string | null | undefined,
   resolveOptions: InternalResolveOptions,
+  targetWeb: boolean,
   depsOptimizer: DepsOptimizer,
-  ssr: boolean,
 ): Promise {
   // TODO: we need to wait until scanning is done here as this function
   // is used in the preAliasPlugin to decide if an aliased dep is optimized,
@@ -972,22 +970,17 @@ export async function tryOptimizedResolve(
     // lazily initialize resolvedSrc
     if (resolvedSrc == null) {
       try {
-        const { target: ssrTarget } = resolveOptions.ssrConfig ?? {}
-        const targetWeb = !ssr || ssrTarget === 'webworker'
-        const resolved = tryNodeResolve(
+        const resolveResult = tryNodeResolveCore(
           id,
           importer,
           resolveOptions,
           targetWeb,
-          undefined,
-          ssr,
-          false,
         )
-        if (resolved?.id) {
-          resolvedSrc = normalizePath(resolved.id)
-        } else {
+        if (resolveResult.resultType !== 'success') {
           // no resolvedSrc, no need to continue
           break
+        } else {
+          resolvedSrc = normalizePath(resolveResult.resolved)
         }
       } catch {
         // this is best-effort only so swallow errors

From c58bb0c2bd92cc630f8c783339c947d56e22d872 Mon Sep 17 00:00:00 2001
From: csr632 <632882184@qq.com>
Date: Sun, 8 Jan 2023 22:40:33 +0800
Subject: [PATCH 7/9] improve tryNodeResolveCore return value

---
 packages/vite/src/node/plugins/resolve.ts | 12 +++++++-----
 packages/vite/src/node/utils.ts           |  8 ++++++++
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts
index 74eebd880266f2..b5807cc5acfc1b 100644
--- a/packages/vite/src/node/plugins/resolve.ts
+++ b/packages/vite/src/node/plugins/resolve.ts
@@ -16,6 +16,7 @@ import {
   SPECIAL_QUERY_RE,
 } from '../constants'
 import {
+  assertUnreachable,
   bareImportRE,
   cleanUrl,
   createDebugger,
@@ -613,7 +614,7 @@ export type TryNodeResolveCoreResult =
       nearestPkg: PackageData
       isDeepImport: boolean
     }
-  | { resultType: 'optional-peer-dep'; resolved: string }
+  | { resultType: 'fail-as-optional-peer-dep'; resolved: string }
   | { resultType: 'fail' }
 
 export function tryNodeResolveCore(
@@ -723,7 +724,7 @@ export function tryNodeResolveCore(
           mainPkg.peerDependenciesMeta?.[nestedPath]?.optional
         ) {
           return {
-            resultType: 'optional-peer-dep',
+            resultType: 'fail-as-optional-peer-dep',
             resolved: `${optionalPeerDepId}:${nestedPath}:${mainPkg.name}`,
           }
         }
@@ -785,12 +786,13 @@ export function tryNodeResolve(
 ): PartialResolvedId | undefined {
   const coreResult = tryNodeResolveCore(id, importer, options, targetWeb)
   if (coreResult.resultType === 'fail') return
-  if (coreResult.resultType === 'optional-peer-dep')
+  if (coreResult.resultType === 'fail-as-optional-peer-dep')
     return {
       id: coreResult.resolved,
     }
-  if (coreResult.resultType !== 'success')
-    throw new Error('assertion error: unexpected coreResult.resultType')
+  if (coreResult.resultType !== 'success') {
+    return assertUnreachable(coreResult)
+  }
 
   const { pkg, pkgId, nearestPkg, isDeepImport } = coreResult
   let { resolved } = coreResult
diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts
index 13ef1c8c91326e..537ee7ab981c0b 100644
--- a/packages/vite/src/node/utils.ts
+++ b/packages/vite/src/node/utils.ts
@@ -1263,3 +1263,11 @@ export function evalValue(rawValue: string): T {
   `)
   return fn()
 }
+
+/**
+ * let typescript do exhaustive check to ensure we have handled all cases
+ * https://stackoverflow.com/a/39419171
+ */
+export function assertUnreachable(x: never): never {
+  throw new Error("Didn't expect to get here")
+}

From 3b57c27c3c3a768ec4cb2d370b52e6a0a7650578 Mon Sep 17 00:00:00 2001
From: csr632 <632882184@qq.com>
Date: Sun, 8 Jan 2023 23:04:31 +0800
Subject: [PATCH 8/9] call tryNodeResolveCore insead of tryNodeResolve to
 reduce mental burden

---
 packages/vite/src/node/config.ts              | 12 +++++++++---
 packages/vite/src/node/ssr/ssrModuleLoader.ts | 14 ++++++++++----
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts
index a78079b0b57386..99bb1c72d9106f 100644
--- a/packages/vite/src/node/config.ts
+++ b/packages/vite/src/node/config.ts
@@ -53,7 +53,7 @@ import type {
   InternalResolveOptionsWithOverrideConditions,
   ResolveOptions,
 } from './plugins/resolve'
-import { resolvePlugin, tryNodeResolve } from './plugins/resolve'
+import { resolvePlugin, tryNodeResolveCore } from './plugins/resolve'
 import type { LogLevel, Logger } from './logger'
 import { createLogger } from './logger'
 import type { DepOptimizationConfig, DepOptimizationOptions } from './optimizer'
@@ -997,12 +997,18 @@ async function bundleConfigFile(
               }
 
               const isIdESM = isESM || kind === 'dynamic-import'
-              let idFsPath = tryNodeResolve(
+              let idFsPath: undefined | string
+              const resolveResult = tryNodeResolveCore(
                 id,
                 importer,
                 { ...options, isRequire: !isIdESM },
                 false,
-              )?.id
+              )
+              if (
+                resolveResult.resultType === 'success' ||
+                resolveResult.resultType === 'fail-as-optional-peer-dep'
+              )
+                idFsPath = resolveResult.resolved
               if (idFsPath && isIdESM) {
                 idFsPath = pathToFileURL(idFsPath).href
               }
diff --git a/packages/vite/src/node/ssr/ssrModuleLoader.ts b/packages/vite/src/node/ssr/ssrModuleLoader.ts
index 4cb226de83944e..e6a91481e88dde 100644
--- a/packages/vite/src/node/ssr/ssrModuleLoader.ts
+++ b/packages/vite/src/node/ssr/ssrModuleLoader.ts
@@ -2,6 +2,7 @@ import path from 'node:path'
 import { pathToFileURL } from 'node:url'
 import type { ViteDevServer } from '../server'
 import {
+  assertUnreachable,
   dynamicImport,
   isBuiltin,
   unwrapId,
@@ -9,7 +10,7 @@ import {
 } from '../utils'
 import { transformRequest } from '../server/transformRequest'
 import type { InternalResolveOptionsWithOverrideConditions } from '../plugins/resolve'
-import { tryNodeResolve } from '../plugins/resolve'
+import { tryNodeResolveCore } from '../plugins/resolve'
 import {
   ssrDynamicImportKey,
   ssrExportAllKey,
@@ -230,7 +231,7 @@ async function nodeImport(
   if (id.startsWith('node:') || isBuiltin(id)) {
     url = id
   } else {
-    const resolved = tryNodeResolve(
+    const resolveResult = tryNodeResolveCore(
       id,
       importer,
       // Non-external modules can import ESM-only modules, but only outside
@@ -241,14 +242,19 @@ async function nodeImport(
         : resolveOptions,
       false,
     )
-    if (!resolved) {
+    if (
+      resolveResult.resultType === 'success' ||
+      resolveResult.resultType === 'fail-as-optional-peer-dep'
+    ) {
+      url = resolveResult.resolved
+    } else {
+      if (resolveResult.resultType !== 'fail') assertUnreachable(resolveResult)
       const err: any = new Error(
         `Cannot find module '${id}' imported from '${importer}'`,
       )
       err.code = 'ERR_MODULE_NOT_FOUND'
       throw err
     }
-    url = resolved.id
     if (usingDynamicImport) {
       url = pathToFileURL(url).toString()
     }

From a1d50f6050a5255b56605bba08281889753c1f58 Mon Sep 17 00:00:00 2001
From: csr632 <632882184@qq.com>
Date: Sun, 8 Jan 2023 23:20:16 +0800
Subject: [PATCH 9/9] cleanup

---
 packages/vite/src/node/plugins/preAlias.ts | 3 +--
 packages/vite/src/node/plugins/resolve.ts  | 4 +---
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/packages/vite/src/node/plugins/preAlias.ts b/packages/vite/src/node/plugins/preAlias.ts
index 92dae6a2f84990..a1a06c5c5cbc68 100644
--- a/packages/vite/src/node/plugins/preAlias.ts
+++ b/packages/vite/src/node/plugins/preAlias.ts
@@ -28,8 +28,7 @@ export function preAliasPlugin(
   const findPatterns = getAliasPatterns(config.resolve.alias)
   const isConfiguredAsExternal = createIsConfiguredAsSsrExternal(config)
   const isBuild = config.command === 'build'
-  const { ssrConfig } = resolveOptions
-  const { target: ssrTarget } = ssrConfig ?? {}
+  const ssrTarget = resolveOptions.ssrConfig?.target
 
   return {
     name: 'vite:pre-alias',
diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts
index b5807cc5acfc1b..9b20ed0676fcf7 100644
--- a/packages/vite/src/node/plugins/resolve.ts
+++ b/packages/vite/src/node/plugins/resolve.ts
@@ -790,9 +790,7 @@ export function tryNodeResolve(
     return {
       id: coreResult.resolved,
     }
-  if (coreResult.resultType !== 'success') {
-    return assertUnreachable(coreResult)
-  }
+  if (coreResult.resultType !== 'success') return assertUnreachable(coreResult)
 
   const { pkg, pkgId, nearestPkg, isDeepImport } = coreResult
   let { resolved } = coreResult