From 3bbe85b778ab99ba1b77c72e68f8ec444c8184e8 Mon Sep 17 00:00:00 2001 From: Shubh Porwal Date: Wed, 9 Sep 2026 00:38:26 +0530 Subject: [PATCH] Exclude regenerator-runtime from production bundles `setUpRegeneratorRuntime` decides at runtime whether generators are native and only then requires `regenerator-runtime/runtime`. Metro collects dependencies statically, so the `require` is followed regardless and the runtime ships in every release bundle even though the branch never executes there: the Babel preset only lowers generators for Hermes development builds (`enableRegenerator = isHermesProfile && dev`), and both Hermes and JSC provide native generators. Wrap the probe and the polyfill in `if (__DEV__)`. Metro's inline and constant-folding passes remove the block before dependency collection, so the module and its `require` edge drop out of production bundles. Development builds are unchanged. Changelog: [GENERAL] [CHANGED] - Exclude `regenerator-runtime` from production bundles. Co-Authored-By: Claude Fable 5.1 --- .../Libraries/Core/setUpRegeneratorRuntime.js | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/packages/react-native/Libraries/Core/setUpRegeneratorRuntime.js b/packages/react-native/Libraries/Core/setUpRegeneratorRuntime.js index c334acca7cdd..8bf56b6b571e 100644 --- a/packages/react-native/Libraries/Core/setUpRegeneratorRuntime.js +++ b/packages/react-native/Libraries/Core/setUpRegeneratorRuntime.js @@ -18,29 +18,33 @@ const {polyfillGlobal} = require('../Utilities/PolyfillFunctions'); * You can use this module directly, or just require InitializeCore. */ -let hasNativeGenerator; -try { - // If this function was lowered by regenerator-transform, it will try to - // access `global.regeneratorRuntime` which doesn't exist yet and will throw. - hasNativeGenerator = hasNativeConstructor( - function* () {}, - 'GeneratorFunction', - ); -} catch { - // In this case, we know generators are not provided natively. - hasNativeGenerator = false; -} +// The preset only lowers generators in development builds, so the runtime is +// only needed there. Gating on __DEV__ keeps it out of production bundles. +if (__DEV__) { + let hasNativeGenerator; + try { + // If this function was lowered by regenerator-transform, it will try to + // access `global.regeneratorRuntime` which doesn't exist yet and will throw. + hasNativeGenerator = hasNativeConstructor( + function* () {}, + 'GeneratorFunction', + ); + } catch { + // In this case, we know generators are not provided natively. + hasNativeGenerator = false; + } -// If generators are provided natively, which suggests that there was no -// regenerator-transform, then there is no need to set up the runtime. -if (!hasNativeGenerator) { - polyfillGlobal('regeneratorRuntime', () => { - // The require just sets up the global, so make sure when we first - // invoke it the global does not exist - delete global.regeneratorRuntime; + // If generators are provided natively, which suggests that there was no + // regenerator-transform, then there is no need to set up the runtime. + if (!hasNativeGenerator) { + polyfillGlobal('regeneratorRuntime', () => { + // The require just sets up the global, so make sure when we first + // invoke it the global does not exist + delete global.regeneratorRuntime; - // regenerator-runtime/runtime exports the regeneratorRuntime object, so we - // can return it safely. - return require('regenerator-runtime/runtime'); // flowlint-line untyped-import:off - }); + // regenerator-runtime/runtime exports the regeneratorRuntime object, so we + // can return it safely. + return require('regenerator-runtime/runtime'); // flowlint-line untyped-import:off + }); + } }