perf: stop dependency cycle resolution earlier

This commit is contained in:
Zoltan Kochan
2020-09-02 15:38:44 +03:00
parent 686cc68f5b
commit a43c12afea
3 changed files with 33 additions and 1 deletions

View File

@@ -0,0 +1,12 @@
---
"@pnpm/resolve-dependencies": minor
---
We are building the dependency tree only until there are new packages or the packages repeat in a unique order. This is needed later during peer dependencies resolution.
So we resolve `foo > bar > qar > foo`.
But we stop on `foo > bar > qar > foo > qar`.
In the second example, there's no reason to walk qar again when qar is included the first time, the dependencies of foo are already resolved and included as parent dependencies of qar. So during peers resolution, qar cannot possibly get any new or different peers resolved, after the first ocurrence.
However, in the next example we would analyze the second qar as well, because zoo is a new parent package:
`foo > bar > qar > zoo > qar`

View File

@@ -1,5 +1,10 @@
export function nodeIdContainsSequence (nodeId: string, pkgId1: string, pkgId2: string) {
return nodeId.includes(`>${pkgId1}>${pkgId2}>`)
const pkgIds = splitNodeId(nodeId)
pkgIds.pop()
const pkg1Index = pkgIds.indexOf(pkgId1)
if (pkg1Index === -1) return false
const pkg2Index = pkgIds.indexOf(pkgId2)
return pkg2Index > -1 && pkg1Index < pkg2Index
}
export function createNodeId (parentNodeId: string, pkgId: string) {

View File

@@ -595,6 +595,21 @@ async function resolveDependency (
}
}
// We are building the dependency tree only until there are new packages
// or the packages repeat in a unique order.
// This is needed later during peer dependencies resolution.
//
// So we resolve foo > bar > qar > foo
// But we stop on foo > bar > qar > foo > qar
// In the second example, there's no reason to walk qar again
// when qar is included the first time, the dependencies of foo
// are already resolved and included as parent dependencies of qar.
// So during peers resolution, qar cannot possibly get any new or different
// peers resolved, after the first ocurrence.
//
// However, in the next example we would analyze the second qar as well,
// because zoo is a new parent package:
// foo > bar > qar > zoo > qar
if (
nodeIdContainsSequence(
options.parentPkg.nodeId,