Install globalEvalWithSourceUrl on bridgeless ReactInstance - #58718
abzokhattab wants to merge 2 commits into
Conversation
Bridge mode already exposes this helper from JSIExecutor so Metro debug loaders can evaluate fetched JS via JSI. Hermes rejects JS eval() of Metro __d(...) source, so lazy chunks fail on New Architecture.
|
Hi @abzokhattab! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
@fabriziocucci has imported this pull request. If you are a Meta employee, you can view this in D122329977. |
|
I don't think this addresses your problem. "Parsing source code unsupported" comes from Hermes and means the engine was built without eval support (HERMESVM_LEAN) |
|
Thanks for taking a look. I agree that message is Hermes rejecting runtime parse (no compiler /
typeof global.globalEvalWithSourceUrl
// bridgeless: "undefined"
// bridge: "function"If this VM were fully unable to compile source, the main Metro bundle would fail the same way. It does not. The gap is only that split-bundle loaders fall back to JS Happy to add a more targeted test if you want (call the helper with a small |
|
Please add a test (eg fantom?) documenting the difference in behaviour between eval and the globalEval |
Document that the helper is installed on the New Architecture runtime and can evaluate Metro-shaped source, including how that compares to JS eval().
|
Added the following test:
The first assertion is the bridgeless gap (helper missing → fail; installed → pass). |
Summary:
Problem: In a New Architecture (bridgeless) debug app, Metro lazy chunks fail with:
This happens on
import()/React.lazy()after first paint. The main bundle still loads.Root cause: Bridgeless never installs
global.globalEvalWithSourceUrl. Bridge mode still does, inJSIExecutor::initializeRuntime.React Native's debug loader (
Libraries/Core/Devtools/loadBundleFromServer.js) already uses that helper so Metro source is evaluated through JSIRuntime::evaluateJavaScriptinstead of JSeval(). Hermes does not supporteval()of Metro__d(...)bundles. Without the helper, split chunks fall through toeval()and throw. Native still loads the main bundle withevaluateJavaScript, so that path works.Fix: Port the existing
JSIExecutorbinding intoReactInstance::initializeRuntimeso bridgeless exposes the same helper.Changelog:
[General] [Fixed] - Install globalEvalWithSourceUrl on bridgeless ReactInstance so Metro lazy chunks can be evaluated via JSI
Test Plan:
ReactInstanceTest.testGlobalEvalWithSourceUrlIsInstalledasserts the helper is installed afterinitializeRuntimeand can evaluate JS.typeof global.globalEvalWithSourceUrl. Expect'function'after this change (undefinedbefore).typeof global.globalEvalWithSourceUrlremains'function'.React.lazy(() => import('./SomeModule'))after first paint. The split chunk should load withoutParsing source code unsupported.