Replies: 1 comment
|
Thank you for the incredibly detailed and well-isolated bug report! Reports of this quality make investigating edge cases significantly easier. Based on Metro's historical behavior with Watchman and symlinks, your hypotheses are spot on. Let's break down exactly what is likely happening here: 1. The "Atomic Directory Replacement" Issue (Hypothesis 2)This is almost certainly the primary culprit. Build tools like When a directory is deleted and recreated rapidly, Watchman correctly fires deletion and creation events. However, Metro's internal 2. The Symlink Path-Identity Mismatch (Hypothesis 1)This exacerbates the first issue. Watchman watches the real path ( The "Single Save" Isolation ExperimentYour suggested experiment is exactly the right next step. If you open The Workaround is Actually the Recommended PatternWhile this is a valid bug in Metro's file-watching pipeline, your workaround—using By bypassing the
We would love to see the results of your single-editor-save experiment. If you confirm it works on a single save, we can track this specifically as a |
Uh oh!
There was an error while loading. Please reload this page.
Environment
| -- | -- metro / metro-resolver | 0.84.3 react-native | 0.86.0 (New Architecture / Fabric) expo / @expo/metro-config | SDK 57.0.4 Package manager | Bun 1.3.14, isolated linker (linker = "isolated") Watchman | 2025.02.17.00 (installed & used) OS | macOS (Apple Silicon)Summary
In a monorepo, an app consumes an internal workspace package that is symlinked into the app's
node_modulesand imported through its built output (dist). When that package's files change on disk (a rebuild), the running Metro server does not reflect the change: Fast Refresh doesn't fire, manual reload (r) re-serves the stale bundle, and only killing + restarting the Metro process picks it up.We understand
rdoesn't force a filesystem re-crawl by design — the concern is that Metro's watcher/invalidation never registers the change at all, so nothing short of a restart works.Setup
packages/ui/dist/components/<name>/index.js.watchFoldersincludespackages/ui(Expo'sgetDefaultConfigauto-adds every workspace pkg — verified).Repro
packages/ui(changesdist/.../index.js; in our casetsdown, batch writes). 3. Fast Refresh and/orr→ still runs the old package code. 4. Kill + restart Metro → change appears.Expected
A change to a file inside a
watchFolder— even reached through anode_modulessymlink to a workspace package — should invalidate the module and trigger HMR / be served on next reload, without a full restart.Ruled out
watchFolders(package dir is watched) · Watchman missing (installed/healthy) · symlink resolution (works cold).Hypotheses for maintainers
Isolation suggestion: with the same setup, do a single plain editor save (no build tool) to a file the app imports. Fails too → pure symlink watch bug; succeeds → the atomic/batch-write-through-symlink path is the trigger. Happy to share a minimal Expo repo.
Workaround
Dev-only
resolver.resolveRequestrewriting@scope/*fromdistto the absolutepackages/ui/src/...path (nonode_modulessegment) — after which edits hot-reload reliably.Two notes:
@scope/ui,tsdown-agnostic wording) so it's a clean upstream repro, not tied to your package names.All reactions