From 3a112c714e7624100f58cc012b944bd5d19d50be Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Wed, 14 Dec 2022 04:09:27 +0200 Subject: [PATCH] perf: don't fetch deps that are already in node_modules, when node-linker=hoisted is used --- pkg-manager/core/src/install/index.ts | 2 + pkg-manager/headless/src/index.ts | 1 + .../headless/src/linkHoistedModules.ts | 56 ++++++++++--------- .../headless/src/lockfileToHoistedDepGraph.ts | 43 ++++++++------ 4 files changed, 57 insertions(+), 45 deletions(-) diff --git a/pkg-manager/core/src/install/index.ts b/pkg-manager/core/src/install/index.ts index a44047f38c9..00c8392791e 100644 --- a/pkg-manager/core/src/install/index.ts +++ b/pkg-manager/core/src/install/index.ts @@ -344,6 +344,7 @@ export async function mutateModules ( nodeVersion: opts.nodeVersion, pnpmVersion: opts.packageManager.name === 'pnpm' ? opts.packageManager.version : '', }, + currentDependenciesLocations: ctx.modulesFile?.locations, patchedDependencies: patchedDependenciesWithResolvedPath, selectedProjectDirs: projects.map((project) => project.rootDir), allProjects: ctx.projects, @@ -1177,6 +1178,7 @@ const installInContext: InstallFunction = async (projects, ctx, opts) => { nodeVersion: opts.nodeVersion, pnpmVersion: opts.packageManager.name === 'pnpm' ? opts.packageManager.version : '', }, + currentDependenciesLocations: ctx.modulesFile?.locations, selectedProjectDirs: projects.map((project) => project.rootDir), allProjects: ctx.projects, prunedAt: ctx.modulesFile?.prunedAt, diff --git a/pkg-manager/headless/src/index.ts b/pkg-manager/headless/src/index.ts index ceac09271fe..6a62c33c250 100644 --- a/pkg-manager/headless/src/index.ts +++ b/pkg-manager/headless/src/index.ts @@ -120,6 +120,7 @@ export interface HeadlessOptions { hoistedDependencies: HoistedDependencies hoistPattern?: string[] publicHoistPattern?: string[] + currentDependenciesLocations?: Record lockfileDir: string modulesDir?: string virtualStoreDir?: string diff --git a/pkg-manager/headless/src/linkHoistedModules.ts b/pkg-manager/headless/src/linkHoistedModules.ts index 5d0fb4bac42..884aa28ebe4 100644 --- a/pkg-manager/headless/src/linkHoistedModules.ts +++ b/pkg-manager/headless/src/linkHoistedModules.ts @@ -95,36 +95,38 @@ async function linkAllPkgsInOrder ( await Promise.all( Object.entries(hierarchy).map(async ([dir, deps]) => { const depNode = graph[dir] - let filesResponse!: PackageFilesResponse - try { - filesResponse = await depNode.fetchingFiles() - } catch (err: any) { // eslint-disable-line - if (depNode.optional) return - throw err - } + if (depNode.fetchingFiles) { + let filesResponse!: PackageFilesResponse + try { + filesResponse = await depNode.fetchingFiles() + } catch (err: any) { // eslint-disable-line + if (depNode.optional) return + throw err + } - let sideEffectsCacheKey: string | undefined - if (opts.sideEffectsCacheRead && filesResponse.sideEffects && !isEmpty(filesResponse.sideEffects)) { - sideEffectsCacheKey = _calcDepState(dir, { - isBuilt: !opts.ignoreScripts && depNode.requiresBuild, - patchFileHash: depNode.patchFile?.hash, - }) - } - const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, { - filesResponse, - force: opts.force || depNode.depPath !== prevGraph[dir]?.depPath, - requiresBuild: depNode.requiresBuild || depNode.patchFile != null, - sideEffectsCacheKey, - }) - if (importMethod) { - progressLogger.debug({ - method: importMethod, - requester: opts.lockfileDir, - status: 'imported', - to: depNode.dir, + let sideEffectsCacheKey: string | undefined + if (opts.sideEffectsCacheRead && filesResponse.sideEffects && !isEmpty(filesResponse.sideEffects)) { + sideEffectsCacheKey = _calcDepState(dir, { + isBuilt: !opts.ignoreScripts && depNode.requiresBuild, + patchFileHash: depNode.patchFile?.hash, + }) + } + const { importMethod, isBuilt } = await storeController.importPackage(depNode.dir, { + filesResponse, + force: opts.force || depNode.depPath !== prevGraph[dir]?.depPath, + requiresBuild: depNode.requiresBuild || depNode.patchFile != null, + sideEffectsCacheKey, }) + if (importMethod) { + progressLogger.debug({ + method: importMethod, + requester: opts.lockfileDir, + status: 'imported', + to: depNode.dir, + }) + } + depNode.isBuilt = isBuilt } - depNode.isBuilt = isBuilt return linkAllPkgsInOrder(storeController, graph, prevGraph, deps, dir, opts) }) ) diff --git a/pkg-manager/headless/src/lockfileToHoistedDepGraph.ts b/pkg-manager/headless/src/lockfileToHoistedDepGraph.ts index 79308e213e0..3110206ae3e 100644 --- a/pkg-manager/headless/src/lockfileToHoistedDepGraph.ts +++ b/pkg-manager/headless/src/lockfileToHoistedDepGraph.ts @@ -32,6 +32,7 @@ export interface LockfileToHoistedDepGraphOptions { externalDependencies?: Set importerIds: string[] include: IncludedDependencies + currentDependenciesLocations?: Record lockfileDir: string nodeVersion: string pnpmVersion: string @@ -176,25 +177,31 @@ async function fetchDeps ( return } const dir = path.join(modules, dep.name) + const depLocation = path.relative(opts.lockfileDir, dir) const resolution = pkgSnapshotToResolution(depPath, pkgSnapshot, opts.registries) let fetchResponse!: ReturnType - try { - fetchResponse = opts.storeController.fetchPackage({ - force: false, - lockfileDir: opts.lockfileDir, - pkg: { - id: packageId, - resolution, - }, - expectedPkg: { - name: pkgName, - version: pkgVersion, - }, - }) - if (fetchResponse instanceof Promise) fetchResponse = await fetchResponse - } catch (err: any) { // eslint-disable-line - if (pkgSnapshot.optional) return - throw err + const skipFetch = opts.currentDependenciesLocations?.[depPath]?.includes(depLocation) + if (skipFetch) { + fetchResponse = {} as any + } else { + try { + fetchResponse = opts.storeController.fetchPackage({ + force: false, + lockfileDir: opts.lockfileDir, + pkg: { + id: packageId, + resolution, + }, + expectedPkg: { + name: pkgName, + version: pkgVersion, + }, + }) + if (fetchResponse instanceof Promise) fetchResponse = await fetchResponse + } catch (err: any) { // eslint-disable-line + if (pkgSnapshot.optional) return + throw err + } } opts.graph[dir] = { alias: dep.name, @@ -222,7 +229,7 @@ async function fetchDeps ( if (!locations[depPath]) { locations[depPath] = [] } - locations[depPath].push(path.relative(opts.lockfileDir, dir)) + locations[depPath].push(depLocation) opts.graph[dir].children = getChildren(pkgSnapshot, opts.pkgLocationsByDepPath, opts) })) return depHierarchy