Skip to content

fix: replace Object.assign with Proxy in flattenModule to preserve live bindings#743

Open
pedrotainha wants to merge 2 commits intooriginjs:mainfrom
pedrotainha:fix/flattenModule-proxy-live-bindings
Open

fix: replace Object.assign with Proxy in flattenModule to preserve live bindings#743
pedrotainha wants to merge 2 commits intooriginjs:mainfrom
pedrotainha:fix/flattenModule-proxy-live-bindings

Conversation

@pedrotainha
Copy link
Copy Markdown

Summary

  • Replace Object.assign({}, module.default, module) with a Proxy in flattenModule to preserve live mutable bindings
  • Save original module reference before reassignment to prevent infinite recursion in Proxy traps

Problem

flattenModule uses Object.assign to create a shallow snapshot of a shared module's exports. This breaks any mutable internal state that is set after module load time.

React 19 stores its hooks dispatcher in __CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.H, which is null at load time and only set during render. The snapshot captures null permanently, causing:

TypeError: Cannot read properties of null (reading 'useMemoCache')

This affects any React hook when using React Compiler (babel-plugin-react-compiler) in federated builds.

Fix

The Proxy delegates property access to the original module object at access time (not load time), preserving live bindings.

Note: The originalModule reference is critical — without it, prop in module after reassignment triggers the Proxy's own has trap recursively (stack overflow).

Test plan

  • Build a host that shares react + react-dom
  • Build a remote with babel-plugin-react-compiler enabled
  • Load remote in host — verify hooks work without crash
  • Verify non-React shared modules still work correctly

Fixes #741

…ve bindings

Object.assign creates a shallow snapshot that breaks mutable internal
state such as React 19 hooks dispatcher (__CLIENT_INTERNALS...H), which
is set at render-time and would be null in the snapshot.

The Proxy delegates property access to the original module object at
access time, preserving live bindings.

Fixes originjs#741
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.

flattenModule uses Object.assign snapshot — breaks mutable internal state (React 19 hooks dispatcher)

1 participant