mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-26 19:12:12 -04:00
* 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)