mirror of
https://github.com/pnpm/pnpm.git
synced 2026-07-21 13:12:46 -04:00
When `runLifecycleHooksConcurrently` re-imports a workspace package into its injected targets after running prepare/postinstall, it has to preserve the existing `node_modules/` inside each target — set up during the initial install (bin symlinks, transitive deps) — while overlaying the script's output (typically a freshly-built `dist/`). The previous approach was a manual `scanDir` over `<targetDir>/node_modules` that fed absolute paths into the re-import's `filesMap`. That worked in 2022 (#4299) when `importIndexedDir` always staged-and-renamed, but #11088 made the fast path (write directly into the final dir) the default. The fast path's `makeEmptyDirSync(targetDir)` wipes the very files the scanned entries point at, so `tryImportIndexedDir`'s first copy throws: ERR_PNPM_ENOENT on <targetDir>/node_modules/.bin/<tool> Reproduces on any workspace package that has a `prepare`/`postinstall` script + a dep with a bin entry, when injected via `injectWorkspacePackages: true` or `dependenciesMeta.<dep>.injected`. Fix: skip the `importPackage` round-trip entirely. After lifecycle scripts complete, iterate the source's `filesMap` (from `fetchFromDir`, which already excludes `node_modules/`) and copy each entry directly into each `targetDir`. The target's existing `node_modules/` is never touched — its bin links + transitive deps stay intact — and there's no tmp-dir staging swap to trip over `.bin/<tool>` symlinks. Regression test in `injectLocalPackages.ts`: an injected workspace package with a `prepublishOnly` script + `@pnpm.e2e/hello-world-js-bin` dep. Before the fix this throws `ERR_PNPM_ENOENT` on `.bin/hello-world-js-bin`; after the fix both the script's output and the bin symlink survive into the injected copy.