Skip to content

Keep react-native/setup-env reachable in the module graph - #57492

Closed
cipolleschi wants to merge 1 commit into
mainfrom
cipolleschi/revert-setup-env-run-before-main
Closed

Keep react-native/setup-env reachable in the module graph#57492
cipolleschi wants to merge 1 commit into
mainfrom
cipolleschi/revert-setup-env-run-before-main

Conversation

@cipolleschi

@cipolleschicipolleschi commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

#57475 pointed Metro's getModulesRunBeforeMainModule at react-native/setup-env (src/setup-env.js) instead of InitializeCore.

But Metro's serializer only emits a run-before-main require for modules already in the bundle graph — see getAppendScripts:

constpaths=[...options.runBeforeMainModule,entryPoint];for(constpathofpaths){if(modules.some(module=>module.path===path)){/* emit run stmt */}}

Nothing imports src/setup-env.js at runtime, so it was silently dropped. The RN environment setup (setUpDefaultReactNativeEnvironment: HMRClient, timers, batched bridge, AppRegistry setup, …) then never ran before the app's main module, and the app redboxed on launch:

Error: Failed to call into JavaScript module method HMRClient.setup().
Module has not been registered as callable.
Registered callable JavaScript modules (n = 1): AppRegistry.

This broke the template E2E tests on both iOS and Android — the app renders a redbox, so Maestro's assertVisible: 'Welcome to React Native' fails (the test (…) jobs are green only because the Maestro step runs with continue-on-error: true; the real failure surfaces via the retry chain and the retry_2 / report job).

Fix

Have the deprecated InitializeCore delegate to 'react-native/setup-env' via a side-effectful require. InitializeCore is a guaranteed graph entry (renderer → ReactNativePrivateInitializeCoreInitializeCore), so this pulls src/setup-env.js into the graph, and getModulesRunBeforeMainModule runs it before the main module again.

Behavior is unchanged: setup-env and InitializeCore both call the idempotent setUpDefaultReactNativeEnvironment(). This keeps #57475's move to setup-env intact rather than reverting it.

Changelog:

[General][Fixed] - Fix app failing to initialize (HMRClient.setup() redbox) because the environment setup module was dropped from the bundle

Test Plan

  • Template E2E (test_e2e_ios_templateapp / test_e2e_android_templateapp) should pass: app launches and shows "Welcome to React Native" instead of the redbox.

cc @huntie (#57475)

@meta-clameta-claBot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 9, 2026
#57475 pointed Metro's getModulesRunBeforeMainModule at
'react-native/setup-env' (src/setup-env.js) instead of InitializeCore.
Metro only runs modules from that list that are already part of the
bundle graph (getAppendScripts: modules.some(m => m.path === path)), and
nothing imports src/setup-env.js at runtime, so it was silently dropped.
The RN environment (HMRClient, timers, batched bridge, AppRegistry
setup...) then no longer ran before the app's main module, producing a
launch-time redbox:
Failed to call into JavaScript module method HMRClient.setup().
Module has not been registered as callable.
This broke the template E2E tests (blank screen, 'Welcome to React
Native' never visible) on both iOS and Android.
Fix: have the deprecated InitializeCore delegate to 'react-native/setup-env'
via a side-effectful require. InitializeCore is a guaranteed graph entry
(via ReactNativePrivateInitializeCore), so this pulls src/setup-env.js
into the graph and getModulesRunBeforeMainModule runs it before main
again. Behavior is unchanged (both ultimately call
setUpDefaultReactNativeEnvironment, which is idempotent).
@cipolleschi
cipolleschiforce-pushed the cipolleschi/revert-setup-env-run-before-main branch from 1a7506e to 77d0d84CompareJuly 9, 2026 09:50
@cipolleschicipolleschi changed the title Point getModulesRunBeforeMainModule back at InitializeCoreKeep react-native/setup-env reachable in the module graphJul 9, 2026

@huntiehuntie left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this catch 🙏🏻

Edit: Just making sure whyInitializeCore.js does get depended on as I can't see a code reference. But if E2E tests pass then let's land.

Edit 2: Found it!: https://github.com/react/react/blob/5123b063a7b3cd5c42ea2be2ccebe4e68d8b12e3/packages/react-native-renderer/src/ReactNativeInjectionShared.js#L17

@meta-codesync

Copy link
Copy Markdown

@huntie has imported this pull request. If you are a Meta employee, you can view this in D111226610.

@meta-codesyncmeta-codesyncBot added the Merged This PR has been merged. label Jul 9, 2026
@meta-codesync

Copy link
Copy Markdown

@huntie merged this pull request in eb987ef.

@huntie
huntie deleted the cipolleschi/revert-setup-env-run-before-main branch July 9, 2026 13:33
meta-codesyncBot pushed a commit that referenced this pull request Jul 10, 2026
Summary:
Pull Request resolved: #57498
**Motivation**
While sanity checking #57492, I double checked why we use `path.join(ctx.reactNativePath, ...)` here when adjacent OOT platforms resolve by package name.
It turns out this complexity is historic and redundant:
- `reactNativePath` doesn't customize the `react-native` package name — it only resolves the `node_modules` directory. [[1]](https://github.com/react-native-community/cli/blame/main/packages/cli-tools/src/findPackageDependencyDir.ts#L81)
- We now (since ~2 years ago) resolve using `{paths: [ctx.root]}`, making the manual `path.join` redundant.
**This diff**
Drops the `reactNativePath` option and resolves `react-native/setup-env` directly by package name.
Purely a refactor. No need to pick to 0.87.
Changelog: [Internal]
Reviewed By: cipolleschi
Differential Revision: D111225671
fbshipit-source-id: ff0a385172228f51cde747266543cc615be7ee38
react-native-bot pushed a commit that referenced this pull request Jul 14, 2026
Summary:
Pull Request resolved: #57498
**Motivation**
While sanity checking #57492, I double checked why we use `path.join(ctx.reactNativePath, ...)` here when adjacent OOT platforms resolve by package name.
It turns out this complexity is historic and redundant:
- `reactNativePath` doesn't customize the `react-native` package name — it only resolves the `node_modules` directory. [[1]](https://github.com/react-native-community/cli/blame/main/packages/cli-tools/src/findPackageDependencyDir.ts#L81)
- We now (since ~2 years ago) resolve using `{paths: [ctx.root]}`, making the manual `path.join` redundant.
**This diff**
Drops the `reactNativePath` option and resolves `react-native/setup-env` directly by package name.
Purely a refactor. No need to pick to 0.87.
Changelog: [Internal]
Reviewed By: cipolleschi
Differential Revision: D111225671
fbshipit-source-id: ff0a385172228f51cde747266543cc615be7ee38
meta-codesyncBot pushed a commit that referenced this pull request Jul 16, 2026
Summary:
Pull Request resolved: #57560
Reverts D112002434.
This fix was needed on `0.87-stable` but not on `main`, since the `setup-env`-in-bundle-graph fix (#57492) was already present, see file at time of D112002434:
https://github.com/react/react-native/blob/08c323346be6c0fbbd70900d48435f977a78a1bb/packages/react-native/Libraries/Core/InitializeCore.js#L30-L37
See #57559 for more info.
Changelog: [Internal]
Reviewed By: zeyap
Differential Revision: D112101450
fbshipit-source-id: 435a24e72415e18b5e3d6a5144ed805adc415a95
react-native-bot pushed a commit that referenced this pull request Jul 16, 2026
Summary:
#57475 pointed Metro's `getModulesRunBeforeMainModule` at `react-native/setup-env` (`src/setup-env.js`) instead of `InitializeCore`.
But Metro's serializer only emits a run-before-main require for modules **already in the bundle graph** — see `getAppendScripts`:
```js
const paths = [...options.runBeforeMainModule, entryPoint];
for (const path of paths) {
if (modules.some(module => module.path === path)) { /* emit run stmt */ }
}
```
Nothing imports `src/setup-env.js` at runtime, so it was silently dropped. The RN environment setup (`setUpDefaultReactNativeEnvironment`: `HMRClient`, timers, batched bridge, `AppRegistry` setup, …) then never ran before the app's main module, and the app **redboxed on launch**:
```
Error: Failed to call into JavaScript module method HMRClient.setup().
Module has not been registered as callable.
Registered callable JavaScript modules (n = 1): AppRegistry.
```
This broke the **template E2E tests** on both iOS and Android — the app renders a redbox, so Maestro's `assertVisible: 'Welcome to React Native'` fails (the `test (…)` jobs are green only because the Maestro step runs with `continue-on-error: true`; the real failure surfaces via the retry chain and the `retry_2 / report` job).
## Fix
Have the deprecated `InitializeCore` delegate to `'react-native/setup-env'` via a side-effectful `require`. `InitializeCore` is a guaranteed graph entry (renderer → `ReactNativePrivateInitializeCore` → `InitializeCore`), so this pulls `src/setup-env.js` into the graph, and `getModulesRunBeforeMainModule` runs it before the main module again.
Behavior is unchanged: `setup-env` and `InitializeCore` both call the idempotent `setUpDefaultReactNativeEnvironment()`. This keeps #57475 move to `setup-env` intact rather than reverting it.
## Changelog:
[General][Fixed] - Fix app failing to initialize (`HMRClient.setup()` redbox) because the environment setup module was dropped from the bundle
Pull Request resolved: #57492
Test Plan:
- Template E2E (`test_e2e_ios_templateapp` / `test_e2e_android_templateapp`) should pass: app launches and shows "Welcome to React Native" instead of the redbox.
cc huntie (#57475)
Reviewed By: cipolleschi
Differential Revision: D111226610
Pulled By: huntie
fbshipit-source-id: b44e82a248c1f2333c2ea85001c9f243b54619ad
react-native-bot pushed a commit that referenced this pull request Jul 16, 2026
Summary:
Pull Request resolved: #57560
Reverts D112002434.
This fix was needed on `0.87-stable` but not on `main`, since the `setup-env`-in-bundle-graph fix (#57492) was already present, see file at time of D112002434:
https://github.com/react/react-native/blob/08c323346be6c0fbbd70900d48435f977a78a1bb/packages/react-native/Libraries/Core/InitializeCore.js#L30-L37
See #57559 for more info.
Changelog: [Internal]
Reviewed By: zeyap
Differential Revision: D112101450
fbshipit-source-id: 435a24e72415e18b5e3d6a5144ed805adc415a95
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA SignedThis label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.MergedThis PR has been merged.p: FacebookPartner: FacebookPartner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@cipolleschi@huntie