Skip to content

fix(arborist): clean up stale .store and hoisted dirs on strategy switch#9649

Merged
owlstronaut merged 1 commit into
release/v11from
backport/v11/9647
Jun 24, 2026
Merged

fix(arborist): clean up stale .store and hoisted dirs on strategy switch#9649
owlstronaut merged 1 commit into
release/v11from
backport/v11/9647

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Backport of #9647 to release/v11.

…tch (#9647)

In continuation of our exploration of using `install-strategy=linked` in
the [Gutenberg
monorepo](WordPress/gutenberg#75814), which
powers the WordPress Block Editor.

Switching `install-strategy` in the same project directory left behind
the previous strategy's layout. Going hoisted → linked kept the stale
real top-level transitive directories alongside the new `.store/` and
symlinks; going linked → hoisted kept the entire `node_modules/.store/`
directory. A fresh install of either strategy was already clean — only
the switch was affected.

## Why

Under the linked strategy the actual tree the diff compares against is
synthesized from the ideal tree (`#buildLinkedActualForDiff`), so real
directories left over from a prior hoisted layout are never seen, and
`#cleanOrphanedTopLevelLinks` only removed symlinks. In the other
direction `load-actual` ignores dot-directories, so the hoisted diff
never sees `node_modules/.store` and never removes it.

## How

`reify.js` now removes the leftover `.store` on a non-linked reify via
`#removeStaleStoreDir`. The store lives only at the project root and is
exclusively a linked artifact, so a single removal covers the project.
It runs only for a full-project install — a workspace-filtered or
`--workspaces=false` install is skipped, because out-of-scope workspaces
may still link into the store.

`#cleanOrphanedTopLevelLinks` (run only under linked) additionally
removes stale real package directories — a directory containing a
`package.json` that is not in the ideal tree's valid top-level set — and
prunes an emptied `@scope` directory afterward. Non-package real
directories and symlinks pointing outside the project are still
preserved.

The valid-top-level collection in `#cleanOrphanedStoreEntries` no longer
skips non-link nodes, so the root's bundled dependencies — materialized
as real top-level directories under linked — are recorded as valid and
never swept as stale.

## References

Fixes #9615
Part of #9608

(cherry picked from commit ca92323)
@owlstronaut owlstronaut merged commit 4c9eacb into release/v11 Jun 24, 2026
33 checks passed
@owlstronaut owlstronaut deleted the backport/v11/9647 branch June 24, 2026 20:09
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.

2 participants