fix(arborist): avoid full reinstall on subsequent linked strategy runs#9031
Open
manzoorwanijk wants to merge 2 commits intonpm:latestfrom
Open
fix(arborist): avoid full reinstall on subsequent linked strategy runs#9031manzoorwanijk wants to merge 2 commits intonpm:latestfrom
manzoorwanijk wants to merge 2 commits intonpm:latestfrom
Conversation
2be33fb to
1e63795
Compare
1e63795 to
7901cd7
Compare
7901cd7 to
38612b1
Compare
Closed
2 tasks
6e585f7 to
d647762
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In continuation of our exploration of using
install-strategy=linkedin the Gutenberg monorepo, which powers the WordPress Block Editor, this is a follow-up of the fixes from #8996.Running
npm install --install-strategy=linkeda second time (with nothing changed) performs a full reinstall instead of recognizing everything is up-to-date. This is because the flat proxy tree built by_createIsolatedTree()doesn't match the nested actual tree fromloadActual(), so the diff marks every package as needing work.There are a few things going wrong:
Proxy link objects created in
processDeps()were missingversion, so the diff always saw a version mismatch (undefined !== "4.1.2") and marked every top-level link as CHANGE.Proxy links used the registry tarball URL for
resolved, but actual links loaded from disk havefile:.store/...URLs. Even with version fixed, the resolved mismatch triggered CHANGE.The proxy tree is flat — all store entries and links are direct children of root. But
loadActual()produces a nested tree where store entries are deep link targets, not visible toallChildren(actual). So every store entry looked like an ADD.binPathswere computed one directory level too deep (join(from.realpath, 'node_modules', '.bin', bn)instead ofjoin(nmFolder, '.bin', bn)), so the bin existence check always failed for store entries with bins.The fix:
versionand correctresolvedon proxy link objects inisolated-reifier.jsbinPathsto point at the right directory level#buildLinkedActualForDiff()inreify.jsthat wraps the actual tree with synthetic entries for store nodes and store links that already exist on disk, so the diff can match themOn a project with 20 direct deps (457 total nodes), a second
npm install --install-strategy=linkednow reports "up to date" in ~0.2s instead of reinstalling everything in ~1.5s.This fix also surfaced a related gap: because the old code always did a full reinstall, it inadvertently cleaned up the
.store/directory on every run. With subsequent installs now correctly skipping unchanged packages, old store entries from updated or removed dependencies would accumulate on disk. A new#cleanOrphanedStoreEntries()method is added to scannode_modules/.store/after each linked install and remove any directories not referenced by the current ideal tree.References
Fixes #6100