Commit Graph

4 Commits

Author SHA1 Message Date
Zoltan Kochan
606f53e78f feat: add dedupePeers option to reduce peer dependency duplication (#11071)
* feat: add `dedupePeers` option to reduce peer dependency duplication

When enabled, this option applies two optimizations to peer dependency resolution:

1. Version-only peer suffixes: Uses name@version instead of full dep paths
   (including nested peer suffixes) when building peer identity hashes.
   This eliminates deeply nested suffixes like (foo@1.0.0(bar@2.0.0)).

2. Transitive peer pruning: Only directly declared peer dependencies are
   included in a package's suffix. Transitive peers from children are not
   propagated upward, preventing combinatorial explosion while maintaining
   correct node_modules layout.

The option is scoped per-project: each workspace project defines a peer
resolution environment, and all packages within that project's tree share
that environment. Projects with different peer versions correctly produce
different instances.

Closes #11070

* fix: pass dedupePeers to getOutdatedLockfileSetting and use spread for lockfile write

The frozen install path (used by approve-builds) calls getOutdatedLockfileSetting
but was missing the dedupePeers parameter. This caused a false LOCKFILE_CONFIG_MISMATCH
error because the lockfile had the key written (as undefined/null via YAML serialization)
while the check function received undefined for the config value.

Fix: pass dedupePeers to the settings check call, and use spread syntax to only write
the dedupePeers key to lockfile settings when it's truthy (avoiding undefined keys).

* fix: write dedupePeers to lockfile like other settings

Write the value directly instead of spread syntax, and use the same
!= null guard pattern as autoInstallPeers in the settings checker.

* test: add integration test for dedupePeers in peerDependencies.ts

* fix: only write dedupePeers to lockfile when enabled

When dedupePeers is false (default), don't write it to lockfile settings.
This avoids adding a new key to every lockfile.

* test: simplify dedupePeers test assertions

* test: check exact snapshot keys in dedupePeers integration test

* test: add workspace test for dedupePeers with different peer versions

* fix: keep transitive peers in suffix with version-only IDs

Instead of pruning transitive peers entirely (which prevented per-project
differentiation), keep them but use version-only identifiers. This way:

- Packages like abc-grand-parent still get a peer suffix when different
  projects provide different peer versions (correct per-project isolation)
- But the suffixes use name@version instead of full dep paths, eliminating
  the nested parentheses that cause combinatorial explosion

* refactor: extract peerNodeIdToPeerId helper in resolvePeers

* refactor: simplify peerNodeIdToPeerId return

* fix: pin peer-a dist tag in dedupePeers tests for CI stability

* fix: address review comments

- Register dedupe-peers in config schema, types, and defaults so
  .npmrc/pnpm-workspace.yaml settings are parsed correctly
- Use Boolean() comparison in settings checker so enabling dedupePeers
  on a pre-existing lockfile triggers re-resolution
- Fix changeset text and test names: transitive peers are still
  propagated, just with version-only IDs (no nested dep paths)
2026-03-24 13:51:17 +01:00
Brandon Cheng
f98a2db373 fix: invalid specifiers for peers on all non-exact version selectors (#11049)
* test: add test for hoist peers when given all range version selectors

* fix: invalid specifiers for peers on non-string version selectors

In tests, the bare specifier for the `@pnpm.e2e/peer-a` dependency
became ` || 1.0.0`. This was because the `versions` array could be
empty, causing the `.join(' || ')` operation to execute on a holey
array.

This caused a test in `installing/commands/test/update/update.ts` to
fail.
2026-03-22 01:47:12 +01:00
Brandon Cheng
021f70d0b0 fix: handle non-string version selectors in hoistPeers (#11048)
* test: add test for version selector with weight in hoistPeers

* fix: handle non-string version selectors in hoistPeers
2026-03-21 23:17:24 +01:00
Zoltan Kochan
8acf2708c9 refactor: rename deps-resolver and env-installer packages (#11013)
Rename @pnpm/installing.resolve-dependencies to @pnpm/installing.deps-resolver
for consistency with the <domain>.<leaf> naming convention.
2026-03-18 21:52:01 +01:00