fix(watch): rebuild when a previously missing file is created#8562
Merged
hyf0 merged 8 commits intorolldown:mainfrom Mar 7, 2026
Merged
fix(watch): rebuild when a previously missing file is created#8562hyf0 merged 8 commits intorolldown:mainfrom
hyf0 merged 8 commits intorolldown:mainfrom
Conversation
When a build fails because an imported file doesn't exist, the watcher now tracks the expected file path so it can detect when the missing file is created and automatically trigger a successful rebuild. Three changes work together: 1. **resolve_utils.rs**: When a path-like import fails with NotFound, compute the expected absolute path and add it to watch_files. 2. **watch_task.rs**: Remove the path.exists() requirement. For non-existing files, watch the parent directory instead (PollWatcher compat). Also clear the resolver cache before each rebuild so previously-failed lookups are re-evaluated. 3. **watch_coordinator.rs**: Filter out file change events that don't match any watched file, preventing spurious rebuilds from unrelated files in watched directories.
hyf0
reviewed
Mar 6, 2026
c88c40b to
6483ee7
Compare
✅ Deploy Preview for rolldown-rs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves rolldown’s watch mode recovery when a build fails due to missing imports by tracking missing-import locations, watching for subsequent filesystem creates/renames, and triggering rebuilds when those changes become relevant.
Changes:
- Track missing-import directories during resolution and expose them via the bundle/plugin driver.
- Extend the watcher to watch missing-import directories and filter fs events to only rebuild on relevant changes.
- Add watch tests for “import missing file then create it” and “import missing file then rename to it”, plus update watch-mode design notes.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/rolldown/tests/watch/watch.test.ts | Adds regression tests for missing-import recovery via create/rename. |
| meta/design/watch-mode.md | Documents the missing-file detection strategy and notify event mapping updates. |
| crates/rolldown_watcher/src/watch_task.rs | Watches missing-import directories and (conditionally) clears resolver cache on rebuild. |
| crates/rolldown_watcher/src/watch_coordinator.rs | Filters out irrelevant file events to avoid spurious rebuilds. |
| crates/rolldown_watcher/src/task_fs_event_handler.rs | Adjusts notify rename event mapping to Create/Delete/Update. |
| crates/rolldown_plugin/src/plugin_driver/plugin_driver_factory.rs | Adds missing_import_dirs storage to the plugin driver. |
| crates/rolldown_plugin/src/plugin_driver/mod.rs | Clears missing_import_dirs on plugin driver reset. |
| crates/rolldown/src/module_loader/resolve_utils.rs | Records missing-import directories on ResolveError::NotFound for path-like specifiers. |
| crates/rolldown/src/bundler/impl_bundler_getter.rs | Adds Bundler::clear_resolver_cache(). |
| crates/rolldown/src/bundle/bundle.rs | Exposes get_missing_import_dirs() from Bundle. |
sapphi-red
approved these changes
Mar 7, 2026
This was referenced Mar 8, 2026
Merged
shulaoda
added a commit
that referenced
this pull request
Mar 9, 2026
## [1.0.0-rc.8] - 2026-03-09 ### 🚀 Features - watch: enable full functional fs watcher in wasm (#8575) by @hyf0 - watch: expose debounce related options (#8572) by @hyf0 ### 🐛 Bug Fixes - detect new URL(…, import.meta.url) with no-sub template literal (#8565) by @char - devtools: trace dynamic imports in devtools (#8581) by @cal-gooo - watch: rebuild when a previously missing file is created (#8562) by @hyf0-agent - watch: filter out Access events to prevent infinite rebuild loop on Linux (#8557) by @hyf0-agent ### 🚜 Refactor - watch: remove auto watch for fail imports (#8585) by @hyf0 - fs_watcher: unify the way of constructing watcher (#8571) by @hyf0 - cli: migrate CLI to CAC (#8551) by @h-a-n-a - switch asset module support from hard-code to builtin plugin (#8546) by @hyf0 ### 📚 Documentation - fix subject-verb agreement in why-bundlers.md (#8591) by @brandonzylstra - maintenance: align release and canary workflow guide (#8538) by @minsoo-web - add `format` option to directives example config (#8590) by @shulaoda - fix: change twitter to x logo in team (#8552) by @mdong1909 - correct composable filter support explanation (#8550) by @sapphi-red ### ⚡ Performance - testing: share tokio runtime across fixture tests (#8567) by @Boshen ### 🧪 Testing - hmr: fix infinite loop in dev server test retry logic (#8576) by @hyf0-agent - cli: add more cli-e2e test cases (#8548) by @h-a-n-a ### ⚙️ Miscellaneous Tasks - docs: update in-depth/directives for `output.strict` option (#8535) by @minsoo-web - add PNPM_HOME Dev Drive mapping to Windows CI workflows (#8589) by @Boshen - deps: update github-actions (#8588) by @renovate[bot] - move Windows cargo target dir to Dev Drive (#8586) by @Boshen - optimize cache keys to fix race conditions and reduce usage (#8578) by @Boshen - remove WASI build & test pipeline (#8580) by @Boshen - remove unnecessary submodule checkouts (#8577) by @Boshen - use Dev Drive for Windows CI jobs (#8574) by @Boshen - skip redundant native binding build for browser and remove standalone job (#8573) by @Boshen - parallelize Node tests on ubuntu, single Node 24 on macOS/windows (#8570) by @Boshen - docs: bump @voidzero-dev/vitepress-theme to 4.8.0 (#8558) by @crusty-voidzero - dedupe type-check from dev server workflow (#8554) by @Boshen ### ❤️ New Contributors * @brandonzylstra made their first contribution in [#8591](#8591) * @char made their first contribution in [#8565](#8565) * @cal-gooo made their first contribution in [#8581](#8581) * @hyf0-agent made their first contribution in [#8562](#8562) * @h-a-n-a made their first contribution in [#8551](#8551) Co-authored-by: shulaoda <165626830+shulaoda@users.noreply.github.com>
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.
When a build fails because an imported file doesn't exist, the watcher now tracks the target directory so it can detect when the missing file is created and automatically trigger a rebuild.
How it works
Key design points
active_missing_dirsis per-build (cleared + repopulated) — stale dirs from fixed imports don't trigger spurious rebuildsregistered_missing_dirsis monotonic — purely prevents redundantnotifyregistrationspackage.json/tsconfigedits also invalidate resolutionsTests
Includes test fixes from #8560 — the tests now use named imports (
import { foo } from './foo.js') instead of side-effect imports (import './foo.js') to avoid tree-shaking removing the imported content from output.All 27 watch tests pass with zero regressions.
Closes the functionality gap noted in #8560.