turbo
3a755475 - fix: Exclude peer dependencies from workspace external dep resolution (#12050)

Commit
1 day ago
fix: Exclude peer dependencies from workspace external dep resolution (#12050) ## Summary Fixes `turbo prune` producing invalid npm lockfiles when workspace packages have peer dependencies satisfied by different versions across apps. Closes #10985 ## Problem When two apps depend on different versions of a package (e.g. `next@14` and `next@15`), npm nests one under the app's `node_modules/` while hoisting the other. After `turbo prune` removes the app that needed the hoisted version, the pruned lockfile still has the old tree structure — a nested version that should now be hoisted. `npm ci` rejects this as inconsistent. ## Fix `NpmLockfile::subgraph` now runs a `rehoist_packages` pass after building the pruned package set. It detects packages nested under a workspace's `node_modules/` whose hoisted counterpart was not explicitly requested by any workspace's transitive closure, and promotes them to the hoisted position with sub-dependencies relocated. The condition `!requested.contains(hoisted_key)` is what distinguishes the issue-10985 case (hoisted v14 pulled in only by a peer dep from the wrong path context — not in any workspace's real transitive closure) from the npm-lock case (hoisted `@types/react` v18 genuinely needed by `web`'s transitive closure). One file changed: `crates/turborepo-lockfiles/src/npm.rs` (+86 lines). ## Testing Verified locally against all relevant fixtures: - `issue-10985`: all 3 targets PASS (app-one, app-two, @repo/components) - `npm-peer-dep`: all 3 PASS - `pnpm-peer-dep`: all 3 PASS - `npm-lock → web`: `@types/react` stays at v18.0.17 (no incorrect rehoisting)
Author
Parents
Loading