Skip to content

fix(build): isolate React into stable vendor chunk to prevent HMR crashes#223

Open
austin-liminal wants to merge 4 commits into
mainfrom
worktree-fix-hmr-react-chunks
Open

fix(build): isolate React into stable vendor chunk to prevent HMR crashes#223
austin-liminal wants to merge 4 commits into
mainfrom
worktree-fix-hmr-react-chunks

Conversation

@austin-liminal
Copy link
Copy Markdown
Contributor

@austin-liminal austin-liminal commented Mar 16, 2026

Summary

  • Adds manual_code_splitting config to the client bundler to force react and react-dom into a dedicated chunk-vendor-[hash].js chunk, preventing React from being co-located in shared app chunks
  • Switches shared chunk filenames from build-ID hashing (chunk-[name]-{buildId}.js) to rolldown's content-based [hash], so the vendor chunk keeps a stable filename across HMR rebuilds and the browser reuses the cached ESM module

Without this fix, HMR would re-import a shared chunk containing React, creating a fresh React instance while the mounted component tree still referenced the old one — causing TypeError: Cannot read properties of null (reading 'useState').

Test plan

  • All 211+ unit/integration tests pass
  • All 29 E2E tests pass (including HMR rebuild test)
  • Coverage at 66% (meets threshold)
  • Clippy clean, zero warnings
  • Manual verification: run cargo run -- dev --root fixtures/basic, edit a page file, confirm no React dispatcher crash on HMR

🤖 Generated with Claude Code

Note

Isolate React into a stable vendor chunk to prevent HMR crashes in client bundle builds

  • Adds manual code splitting in client_bundle.rs to place react and react-dom into a dedicated chunk-vendor-[hash].js chunk, keeping React stable across rebuilds.
  • Fixes the chunk filename template from {hash} to [hash] to align with rolldown's content-hash interpolation syntax.
  • Adds a test in vendor_chunk_tests.rs asserting that the vendor chunk is emitted, contains React symbols, and is referenced by page entries rather than inlined.
  • Behavioral Change: client bundles now emit an additional shared vendor chunk; any downstream asset manifest consumers must handle the new shared_chunks entry.

Macroscope summarized 3faa195.

…shes

React was being co-bundled into shared app chunks by rolldown's automatic
code splitting. During HMR, re-importing the shared chunk created a fresh
React instance while the mounted component tree still referenced the old
one, causing "Cannot read properties of null (reading 'useState')" crashes.

Two changes fix this:
1. Add manual_code_splitting with a vendor group that forces react and
   react-dom into their own chunk
2. Switch shared chunk filenames from build-ID hashing to rolldown's
   content-based [hash], so the vendor chunk keeps a stable filename
   across HMR rebuilds and the browser reuses the cached ESM module

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Mar 16, 2026

Approvability

Verdict: Needs human review

Unable to check for correctness in e5456b6.

No code changes detected at 3faa195. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

claude-liminal and others added 3 commits March 16, 2026 16:53
Verifies that manual_code_splitting isolates React into dedicated
chunk-vendor-*.js files with content-based hashes, and that page
entry chunks import React from the vendor chunk rather than bundling
it inline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@austin-liminal austin-liminal added this pull request to the merge queue Mar 24, 2026
@austin-liminal austin-liminal removed this pull request from the merge queue due to a manual request Mar 24, 2026
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.

1 participant