Repository navigation
feat: incremental make for watch rebuilds - #21556
bjohansebas wants to merge 67 commits into
Conversation
🦋 Changeset detectedLatest commit: 3b8f1f7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
04cfd4b to
9992e43
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #21556 +/- ##
==========================================
- Coverage 96.92% 96.91% -0.01%
==========================================
Files 802 803 +1
Lines 136245 137460 +1215
Branches 46422 46953 +531
==========================================
+ Hits 132055 133222 +1167
- Misses 4190 4238 +48
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
9992e43 to
def7c1a
Compare
ff0c2fb to
520b839
Compare
|
Let’s fix tests and we can merge |
e21d62c to
272a333
Compare
272a333 to
816a091
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3618e21. Configure here.
5ca1c5e to
3e0aa2e
Compare
Revert the partial traversal from 65b1bf4 so changed dependencies can start before retained subtrees finish. Keep invalidation tracking and update the resolution counts.
Exercise an extra invalidation without editing files. Require an entry rebuild when its source changes, while preserving hook and reuse assertions.
Keep the stable request in an unchanged subtree so the option test still distinguishes graph reuse from regular resolution.
Give each compiler a separate filename and execute its own bundle. Keep one compiler from cleaning outputs written by the others.
Keep existing file, context and missing dependency sets when the factory adds no entries. Preserve missing dependency propagation to importers. A common-libs watch build creates 1612 replacement collections instead of 5718, with identical output.

Summary
Makes watch rebuilds incremental: the previous compilation's module graph and module set are reused, changed modules are detected via their build/resolve snapshots and only those are re-factorized and rebuilt — the O(modules) entry re-walk is skipped (on the original branch this measured make 285ms→78ms for a 1-module change on a react-5k project; numbers for this port to be re-measured). No config option: it is automatic in watch mode; compilations that ran build-time execution (
importModule) disable reuse for the rest of the session since execution mutates the durable graph. Fourth PR of the incremental-rebuilds series (stacked on #21555, extracted fromperf/incremental-rebuild).What kind of change does this PR introduce?
feat
Did you add tests for your changes?
Yes,
test/watchCases/incremental/*; and since the behavior is always on in watch mode, the wholeWatchTestCasessuite now exercises it.Does this PR introduce a breaking change?
No; watch rebuilds keep producing identical output, and single (non-watch) builds are untouched.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
n/a
Use of AI
AI (Claude Code) was used to extract this change from my working branch, adapt it onto current
main, and debug the build-time-execution interaction; I reviewed and validated everything locally.Note
High Risk
Touches the core make/seal pipeline and durable module graph semantics; incorrect reuse could cause stale bundles or missed rebuilds across many edge cases (entries, lazy barrels, concat, resolve).
Overview
Watch mode now performs incremental make: when the previous compilation was sealed with a reusable base snapshot and mutation journal, the next watch compilation keeps the module graph, entries, and end-of-make module set, then runs the make hook mainly for entry deduplication before
_incrementalMakescansneedBuild(plus resolve snapshots) and rebuilds only changed modules. Unchanged modules skip dependency re-walks; changed loader/scheme modules can be re-factorized through the factory so resolution changes are picked up, with pruning of unreachable modules and reversal of seal-time graph mutations (e.g. concatenation) viaModuleGraphjournal APIs.Compilerretains_lastCompilationacross watch cycles (without clearing module graph state), gates reuse on_incrementalReadyand disables it permanently afterexecuteModule/importModule. Seal snapshots base module maps, starts the mutation journal, and cleans up parsers; finish paths reset export/usage flags and extend mem-cache reference keys with connection active state so side-effect optimizations still invalidate correctly.Adds a minor changeset and broad
test/watchCases/incremental/*coverage (entries, loaders, concat, side effects, errors, dynamic entries).Reviewed by Cursor Bugbot for commit 3e0aa2e. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation