Skip to content

fix: support npm install-strategy=linked (.store layout)#596

Open
manzoorwanijk wants to merge 1 commit intods300:masterfrom
manzoorwanijk:fix/support-npm-linked-install-strategy
Open

fix: support npm install-strategy=linked (.store layout)#596
manzoorwanijk wants to merge 1 commit intods300:masterfrom
manzoorwanijk:fix/support-npm-linked-install-strategy

Conversation

@manzoorwanijk
Copy link

Summary

  • Add resolvePackagePath utility that locates packages when they aren't at the expected node_modules/ path, with two fallback strategies:
    1. Search node_modules/.store/ for npm install-strategy=linked layouts
    2. Walk up ancestor directories for monorepo-hoisted packages
  • Remap diff paths in parsed patches before applying, so patches target the actual package location
  • Thread the resolved path through state file operations (getPatchApplicationState, savePatchApplicationState, clearPatchApplicationState)
  • Use the resolver in makePatch so patch creation also works with non-standard layouts

Fixes #595, partially addresses #277

Context

npm's experimental install-strategy=linked stores packages in node_modules/.store/<pkg>@<version>-<hash>/node_modules/<pkg>/ and creates symlinks. For nested dependencies in monorepo/workspace setups, the symlink may not exist at the path patch-package expects (e.g. node_modules/parent/node_modules/child), causing patch application to fail with "package not present" errors.

Similarly, in monorepos with hoisting (#277), a workspace package's dependency may be installed in the root node_modules/ rather than the workspace's own node_modules/, causing the same failure.

How it works

resolvePackagePath() tries three strategies in order:

  1. Direct path — if the expected node_modules/<pkg> path exists (regular install or working symlink), return immediately with no overhead.
  2. .store search — scan node_modules/.store/ for entries matching <packageName>@<version>*, preferring version-specific matches.
  3. Ancestor walk — walk up parent directories checking each node_modules/ for the package, handling monorepo hoisting.

When the resolved path differs from the original, remapPatchPaths() rewrites the path prefixes in all patch effects (file patches, creations, deletions, renames, mode changes) before executeEffects runs. The resolved path is also passed to state file operations so .patch-package.json is read/written at the correct location.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support npm install-strategy=linked (.store directory layout)

1 participant