From fb904f97348119cc9d70bcc25c1ccd8eff4e0c90 Mon Sep 17 00:00:00 2001 From: patak Date: Sat, 8 Apr 2023 08:24:13 +0200 Subject: [PATCH] perf: avoid side effects resolving in dev and in the optimizer/scanner (#12789) Co-authored-by: Bjorn Lu --- packages/vite/src/node/config.ts | 1 + packages/vite/src/node/plugins/resolve.ts | 51 +++++++++++++++-------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index f4816167fa05e7..7e91c1775a680d 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -594,6 +594,7 @@ export async function resolveConfig( preferRelative: false, tryIndex: true, ...options, + idOnly: true, }), ], })) diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 856c8aa37e9033..52a01652d4cd5d 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -115,6 +115,13 @@ export interface InternalResolveOptions extends Required { // Resolve using esbuild deps optimization getDepsOptimizer?: (ssr: boolean) => DepsOptimizer | undefined shouldExternalize?: (id: string) => boolean | undefined + + /** + * Set by createResolver, we only care about the resolved id. moduleSideEffects + * and other fields are discarded so we can avoid computing them. + * @internal + */ + idOnly?: boolean } export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { @@ -265,7 +272,12 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { // If this isn't a script imported from a .html file, include side effects // hints so the non-used code is properly tree-shaken during build time. - if (!importer?.endsWith('.html')) { + if ( + !options.idOnly && + !options.scan && + options.isBuild && + !importer?.endsWith('.html') + ) { const resPkg = findNearestPackageData( path.dirname(res), options.packageCache, @@ -302,10 +314,7 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { // external if (isExternalUrl(id)) { - return { - id, - external: true, - } + return options.idOnly ? id : { id, external: true } } // data uri: pass through (this only happens during build and will be @@ -377,10 +386,7 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin { this.error(message) } - return { - id, - external: true, - } + return options.idOnly ? id : { id, external: true } } else { if (!asSrc) { debug?.( @@ -773,7 +779,10 @@ export function tryNodeResolve( return { ...resolved, id: resolvedId, external: true } } - if ((isBuild && !depsOptimizer) || externalize) { + if ( + !options.idOnly && + ((!options.scan && isBuild && !depsOptimizer) || externalize) + ) { // Resolve package side effects for build so that rollup can better // perform tree-shaking return processResult({ @@ -853,7 +862,7 @@ export function tryNodeResolve( resolved = depsOptimizer!.getOptimizedDepId(optimizedInfo) } - if (isBuild) { + if (!options.idOnly && !options.scan && isBuild) { // Resolve package side effects for build so that rollup can better // perform tree-shaking return { @@ -1210,16 +1219,22 @@ function tryResolveBrowserMapping( : tryFsResolve(path.join(pkg.dir, browserMappedPath), options)) ) { debug?.(`[browser mapped] ${colors.cyan(id)} -> ${colors.dim(res)}`) - const resPkg = findNearestPackageData( - path.dirname(res), - options.packageCache, - ) - const result = resPkg - ? { + let result: PartialResolvedId = { id: res } + if (options.idOnly) { + return result + } + if (!options.scan && options.isBuild) { + const resPkg = findNearestPackageData( + path.dirname(res), + options.packageCache, + ) + if (resPkg) { + result = { id: res, moduleSideEffects: resPkg.hasSideEffects(res), } - : { id: res } + } + } return externalize ? { ...result, external: true } : result } } else if (browserMappedPath === false) {