From 38690685b517eb3c5b0a8cc659d7968148b9b002 Mon Sep 17 00:00:00 2001 From: bluwy Date: Sun, 12 Mar 2023 18:09:03 +0800 Subject: [PATCH 1/6] refactor(resolve): remove deep import syntax handling --- packages/vite/src/node/optimizer/index.ts | 35 +++++++++++++---- packages/vite/src/node/plugins/resolve.ts | 46 +++++++---------------- 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index c952d7b792d457..a5c206fe897a52 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -18,6 +18,7 @@ import { getHash, isOptimizable, lookupFile, + nestedResolveFrom, normalizeId, normalizePath, removeDir, @@ -812,18 +813,13 @@ export async function addManuallyIncludedOptimizeDeps( ) } } - const resolve = config.createResolver({ - asSrc: false, - scan: true, - ssrOptimizeCheck: ssr, - ssrConfig: config.ssr, - }) + const resolve = createOptimizeDepsIncludeResolver(config, ssr) for (const id of [...optimizeDepsInclude, ...extra]) { // normalize 'foo >bar` as 'foo > bar' to prevent same id being added // and for pretty printing const normalizedId = normalizeId(id) if (!deps[normalizedId] && filter?.(normalizedId) !== false) { - const entry = await resolve(id, undefined, undefined, ssr) + const entry = await resolve(id) if (entry) { if (isOptimizable(entry, optimizeDeps)) { if (!entry.endsWith('?__vite_skip_optimization')) { @@ -840,6 +836,31 @@ export async function addManuallyIncludedOptimizeDeps( } } +function createOptimizeDepsIncludeResolver( + config: ResolvedConfig, + ssr: boolean, +) { + const resolve = config.createResolver({ + asSrc: false, + scan: true, + ssrOptimizeCheck: ssr, + ssrConfig: config.ssr, + }) + return async (id: string) => { + const lastArrowIndex = id.lastIndexOf('>') + if (lastArrowIndex === -1) { + return await resolve(id, undefined, undefined, ssr) + } + // split id by last '>' for nested selected packages, for example: + // 'foo > bar > baz' => 'foo > bar' & 'baz' + // 'foo' => '' & 'foo' + const nestedRoot = id.substring(0, lastArrowIndex).trim() + const nestedPath = id.substring(lastArrowIndex + 1).trim() + const basedir = nestedResolveFrom(nestedRoot, config.root) + return await resolve(nestedPath, basedir, undefined, ssr) + } +} + export function newDepOptimizationProcessing(): DepOptimizationProcessing { let resolve: () => void const promise = new Promise((_resolve) => { diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 11db96a2898179..1e0a0e00e37ce5 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -33,7 +33,6 @@ import { isTsRequest, isWindows, lookupFile, - nestedResolveFrom, normalizePath, resolveFrom, slash, @@ -653,24 +652,14 @@ export function tryNodeResolve( 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 possiblePkgIds: string[] = [] for (let prevSlashIndex = -1; ; ) { - let slashIndex = nestedPath.indexOf('/', prevSlashIndex + 1) + let slashIndex = id.indexOf('/', prevSlashIndex + 1) if (slashIndex < 0) { - slashIndex = nestedPath.length + slashIndex = id.length } - const part = nestedPath.slice( - prevSlashIndex + 1, - (prevSlashIndex = slashIndex), - ) + const part = id.slice(prevSlashIndex + 1, (prevSlashIndex = slashIndex)) if (!part) { break } @@ -683,7 +672,7 @@ export function tryNodeResolve( continue } - const possiblePkgId = nestedPath.slice(0, slashIndex) + const possiblePkgId = id.slice(0, slashIndex) possiblePkgIds.push(possiblePkgId) } @@ -700,11 +689,6 @@ export function tryNodeResolve( basedir = root } - // nested node module, step-by-step resolve to the basedir of the nestedPath - if (nestedRoot) { - basedir = nestedResolveFrom(nestedRoot, basedir, preserveSymlinks) - } - let pkg: PackageData | undefined let pkgId: string | undefined // nearest package.json @@ -742,9 +726,9 @@ export function tryNodeResolve( // if so, we can resolve to a special id that errors only when imported. if ( basedir !== root && // root has no peer dep - !isBuiltin(nestedPath) && - !nestedPath.includes('\0') && - bareImportRE.test(nestedPath) + !isBuiltin(id) && + !id.includes('\0') && + bareImportRE.test(id) ) { // find package.json with `name` as main const mainPackageJson = lookupFile(basedir, ['package.json'], { @@ -753,11 +737,11 @@ export function tryNodeResolve( if (mainPackageJson) { const mainPkg = JSON.parse(mainPackageJson) if ( - mainPkg.peerDependencies?.[nestedPath] && - mainPkg.peerDependenciesMeta?.[nestedPath]?.optional + mainPkg.peerDependencies?.[id] && + mainPkg.peerDependenciesMeta?.[id]?.optional ) { return { - id: `${optionalPeerDepId}:${nestedPath}:${mainPkg.name}`, + id: `${optionalPeerDepId}:${id}:${mainPkg.name}`, } } } @@ -767,10 +751,10 @@ export function tryNodeResolve( let resolveId = resolvePackageEntry let unresolvedId = pkgId - const isDeepImport = unresolvedId !== nestedPath + const isDeepImport = unresolvedId !== id if (isDeepImport) { resolveId = resolveDeepImport - unresolvedId = '.' + nestedPath.slice(pkgId.length) + unresolvedId = '.' + id.slice(pkgId.length) } let resolved: string | undefined @@ -865,16 +849,14 @@ export function tryNodeResolve( !isJsType || importer?.includes('node_modules') || exclude?.includes(pkgId) || - exclude?.includes(nestedPath) || + exclude?.includes(id) || SPECIAL_QUERY_RE.test(resolved) || // During dev SSR, we don't have a way to reload the module graph if // a non-optimized dep is found. So we need to skip optimization here. // The only optimized deps are the ones explicitly listed in the config. (!options.ssrOptimizeCheck && !isBuild && ssr) || // Only optimize non-external CJS deps during SSR by default - (ssr && - !isCJS && - !(include?.includes(pkgId) || include?.includes(nestedPath))) + (ssr && !isCJS && !(include?.includes(pkgId) || include?.includes(id))) if (options.ssrOptimizeCheck) { return { From 2318669a674e87ac3f9b183711f64b18b2b7d351 Mon Sep 17 00:00:00 2001 From: bluwy Date: Sun, 12 Mar 2023 18:14:16 +0800 Subject: [PATCH 2/6] refactor: tiny ssr change --- packages/vite/src/node/plugins/resolve.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 1e0a0e00e37ce5..7be77c0d6172f1 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -644,14 +644,12 @@ export function tryNodeResolve( options: InternalResolveOptionsWithOverrideConditions, targetWeb: boolean, depsOptimizer?: DepsOptimizer, - ssr?: boolean, + ssr: boolean = false, externalize?: boolean, allowLinkedExternal: boolean = true, ): PartialResolvedId | undefined { const { root, dedupe, isBuild, preserveSymlinks, packageCache } = options - ssr ??= false - const possiblePkgIds: string[] = [] for (let prevSlashIndex = -1; ; ) { let slashIndex = id.indexOf('/', prevSlashIndex + 1) From 66ecda72b9f4dbed46c97fb9c24edbeefbf99cdf Mon Sep 17 00:00:00 2001 From: bluwy Date: Sun, 12 Mar 2023 18:32:55 +0800 Subject: [PATCH 3/6] fix: handle nestedResolveFrom in ssr --- packages/vite/src/node/optimizer/index.ts | 2 +- packages/vite/src/node/utils.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index a5c206fe897a52..fbe2aac1fe3b46 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -856,7 +856,7 @@ function createOptimizeDepsIncludeResolver( // 'foo' => '' & 'foo' const nestedRoot = id.substring(0, lastArrowIndex).trim() const nestedPath = id.substring(lastArrowIndex + 1).trim() - const basedir = nestedResolveFrom(nestedRoot, config.root) + const basedir = nestedResolveFrom(nestedRoot, config.root, false, ssr) return await resolve(nestedPath, basedir, undefined, ssr) } } diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index b614da2696318c..4cb6931e7317de 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -160,11 +160,12 @@ export function nestedResolveFrom( id: string, basedir: string, preserveSymlinks = false, + ssr = false, ): string { const pkgs = id.split('>').map((pkg) => pkg.trim()) try { for (const pkg of pkgs) { - basedir = resolveFrom(pkg, basedir, preserveSymlinks) + basedir = resolveFrom(pkg, basedir, preserveSymlinks, ssr) } } catch {} return basedir From 2fec50438b94f881ed073d288f75c81a1ccbfd48 Mon Sep 17 00:00:00 2001 From: bluwy Date: Sun, 12 Mar 2023 18:41:39 +0800 Subject: [PATCH 4/6] docs: update comment [skip ci] --- packages/vite/src/node/optimizer/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index fbe2aac1fe3b46..a979c064fd125a 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -853,7 +853,6 @@ function createOptimizeDepsIncludeResolver( } // split id by last '>' for nested selected packages, for example: // 'foo > bar > baz' => 'foo > bar' & 'baz' - // 'foo' => '' & 'foo' const nestedRoot = id.substring(0, lastArrowIndex).trim() const nestedPath = id.substring(lastArrowIndex + 1).trim() const basedir = nestedResolveFrom(nestedRoot, config.root, false, ssr) From ac7fe2b4b2afa9e94cd6bbf62224a0263782a4dc Mon Sep 17 00:00:00 2001 From: bluwy Date: Mon, 13 Mar 2023 00:13:52 +0800 Subject: [PATCH 5/6] chore: trigger ci --- packages/vite/src/node/optimizer/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index a979c064fd125a..516a0c3c841775 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -851,7 +851,7 @@ function createOptimizeDepsIncludeResolver( if (lastArrowIndex === -1) { return await resolve(id, undefined, undefined, ssr) } - // split id by last '>' for nested selected packages, for example: + // split nested selected id by last '>', for example: // 'foo > bar > baz' => 'foo > bar' & 'baz' const nestedRoot = id.substring(0, lastArrowIndex).trim() const nestedPath = id.substring(lastArrowIndex + 1).trim() From 23e5a39ab8a0b0dd301f3c74dc89a8c365fdfb4a Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Mon, 13 Mar 2023 22:08:19 +0800 Subject: [PATCH 6/6] fix: respect preserveSymlinks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 翠 / green --- packages/vite/src/node/optimizer/index.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/optimizer/index.ts b/packages/vite/src/node/optimizer/index.ts index 516a0c3c841775..93989cae446a2f 100644 --- a/packages/vite/src/node/optimizer/index.ts +++ b/packages/vite/src/node/optimizer/index.ts @@ -855,7 +855,12 @@ function createOptimizeDepsIncludeResolver( // 'foo > bar > baz' => 'foo > bar' & 'baz' const nestedRoot = id.substring(0, lastArrowIndex).trim() const nestedPath = id.substring(lastArrowIndex + 1).trim() - const basedir = nestedResolveFrom(nestedRoot, config.root, false, ssr) + const basedir = nestedResolveFrom( + nestedRoot, + config.root, + config.resolve.preserveSymlinks, + ssr, + ) return await resolve(nestedPath, basedir, undefined, ssr) } }