mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-28 02:53:15 -04:00
perf: stop dependency cycle resolution earlier
This commit is contained in:
12
.changeset/unlucky-garlics-fetch.md
Normal file
12
.changeset/unlucky-garlics-fetch.md
Normal 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`
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user