From 1c49a3e10cb1d2c5966b00c5eb696b98bad871ee Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 29 Mar 2023 10:38:26 -0700 Subject: [PATCH 1/2] perf(pkgs-graph): speed up createPkgGraph when directory specifiers are present --- .changeset/twelve-gifts-rescue.md | 5 +++++ workspace/pkgs-graph/src/index.ts | 35 +++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 .changeset/twelve-gifts-rescue.md diff --git a/.changeset/twelve-gifts-rescue.md b/.changeset/twelve-gifts-rescue.md new file mode 100644 index 00000000000..004b2fb250c --- /dev/null +++ b/.changeset/twelve-gifts-rescue.md @@ -0,0 +1,5 @@ +--- +"@pnpm/workspace.pkgs-graph": patch +--- + +Speed up createPkgGraph when directory specifiers are present diff --git a/workspace/pkgs-graph/src/index.ts b/workspace/pkgs-graph/src/index.ts index 008f87d25c9..24a9b44bbd0 100644 --- a/workspace/pkgs-graph/src/index.ts +++ b/workspace/pkgs-graph/src/index.ts @@ -36,12 +36,8 @@ export function createPkgGraph (pkgs: Array, opts?: { } { const pkgMap = createPkgMap(pkgs) const pkgMapValues = Object.values(pkgMap) - const pkgMapByManifestName: Record = {} - for (const pkg of pkgMapValues) { - if (pkg.manifest.name) { - (pkgMapByManifestName[pkg.manifest.name] ??= []).push(pkg) - } - } + const pkgMapByManifestName = getPkgMapByManifestName(pkgMapValues) + let pkgMapByDir: Record | undefined const unmatched: Array<{ pkgName: string, range: string }> = [] const graph = mapValues((pkg) => ({ dependencies: createNode(pkg), @@ -73,10 +69,19 @@ export function createPkgGraph (pkgs: Array, opts?: { } if (spec.type === 'directory') { + pkgMapByDir ??= getPkgMapByDir(pkgMapValues) + const resolvedPath = path.resolve(pkg.dir, spec.fetchSpec) + const found = pkgMapByDir[resolvedPath] + if (found) { + return found.dir + } + + // Slow path; only needed when there are case mismatches on case-insensitive filesystems. const matchedPkg = pkgMapValues.find(pkg => path.relative(pkg.dir, spec.fetchSpec) === '') if (matchedPkg == null) { return '' } + pkgMapByDir[resolvedPath] = matchedPkg return matchedPkg.dir } @@ -120,3 +125,21 @@ function createPkgMap (pkgs: Package[]): Record { } return pkgMap } + +function getPkgMapByManifestName (pkgMapValues: Package[]) { + const pkgMapByManifestName: Record = {} + for (const pkg of pkgMapValues) { + if (pkg.manifest.name) { + (pkgMapByManifestName[pkg.manifest.name] ??= []).push(pkg) + } + } + return pkgMapByManifestName +} + +function getPkgMapByDir (pkgMapValues: Package[]) { + const pkgMapByDir: Record = {} + for (const pkg of pkgMapValues) { + pkgMapByDir[path.resolve(pkg.dir)] = pkg + } + return pkgMapByDir +} From 05a10d5e78d14fedf34db37cadb4b67d561d9a13 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 29 Mar 2023 10:48:05 -0700 Subject: [PATCH 2/2] perf(pkgs-graph): make pkgMapByManifestName equally lazy --- workspace/pkgs-graph/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workspace/pkgs-graph/src/index.ts b/workspace/pkgs-graph/src/index.ts index 24a9b44bbd0..8bbfa9974b2 100644 --- a/workspace/pkgs-graph/src/index.ts +++ b/workspace/pkgs-graph/src/index.ts @@ -36,7 +36,7 @@ export function createPkgGraph (pkgs: Array, opts?: { } { const pkgMap = createPkgMap(pkgs) const pkgMapValues = Object.values(pkgMap) - const pkgMapByManifestName = getPkgMapByManifestName(pkgMapValues) + let pkgMapByManifestName: Record | undefined let pkgMapByDir: Record | undefined const unmatched: Array<{ pkgName: string, range: string }> = [] const graph = mapValues((pkg) => ({ @@ -87,6 +87,7 @@ export function createPkgGraph (pkgs: Array, opts?: { if (spec.type !== 'version' && spec.type !== 'range') return '' + pkgMapByManifestName ??= getPkgMapByManifestName(pkgMapValues) const pkgs = pkgMapByManifestName[depName] if (!pkgs || pkgs.length === 0) return '' const versions = pkgs.filter(({ manifest }) => manifest.version)