Skip to content

Allow configuring Babel runtime via caller in @react-native/babel-preset (#57974) - #57974

Closed
robhogan wants to merge 1 commit into
mainfrom
export-D114070686
Closed

robhogan wants to merge 1 commit into
mainfrom
export-D114070686

Conversation

@robhogan

@robhogan robhogan commented Aug 17, 2026 •

Copy link
Copy Markdown
Collaborator

Summary:

Adds a mechanism for callers to configure babel/plugin-transform-runtime
programmatically via Babel caller data, in addition to preset options.

  • enableBabelRuntime (boolean toggle, or a string to pin a specific
    babel/runtime version) can now be read from the Babel caller.
  • babelRuntimeModuleName (the module helpers are imported from) can be
    provided via preset options or the Babel caller.

Both values are passed as separate primitives (Babel only permits primitive
caller values). Preset options take precedence over caller data, consistent
with how unstable_transformProfile is resolved.

Changelog:
[General][Added] - Allow react-native/babel-preset to read enableBabelRuntime and babelRuntimeModuleName from Babel caller data

Reviewed By: vzaidman

Differential Revision: D114070686

@meta-cla meta-cla Bot 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 Aug 17, 2026
@meta-codesync

meta-codesync Bot commented Aug 17, 2026

Copy link
Copy Markdown

@robhogan has exported this pull request. If you are a Meta employee, you can view the originating Diff in D114070686.

@meta-codesync meta-codesync Bot changed the title Allow configuring Babel runtime via caller in @react-native/babel-preset Allow configuring Babel runtime via caller in @react-native/babel-preset (#57974) Aug 17, 2026
meta-codesync Bot pushed a commit that referenced this pull request Aug 17, 2026
…set (#57974)

Summary:

Adds a mechanism for callers to configure `babel/plugin-transform-runtime`
programmatically via Babel caller data, in addition to preset options.

- `enableBabelRuntime` (boolean toggle, or a string to pin a specific
  `babel/runtime` version) can now be read from the Babel caller.
- `babelRuntimeModuleName` (the module helpers are imported from) can be
  provided via preset options or the Babel caller.

Both values are passed as separate primitives (Babel only permits primitive
caller values). Preset options take precedence over caller data, consistent
with how `unstable_transformProfile` is resolved.

Changelog:
[General][Added] - Allow `react-native/babel-preset` to read `enableBabelRuntime` and `babelRuntimeModuleName` from Babel caller data

Reviewed By: vzaidman

Differential Revision: D114070686
@meta-codesync
meta-codesync Bot force-pushed the export-D114070686 branch from 7c3dca6 to 683dc7c Compare August 17, 2026 14:32
@retyui

retyui commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

will this help to fix this issue?

#57123

@robhogan

Copy link
Copy Markdown
Collaborator Author

@cortinico / @vzaidman / @cipolleschi - IIRC this was mid-land when I left, I think it's already approved. Could someone help land it?

meta-codesync Bot pushed a commit that referenced this pull request Sep 21, 2026
…set (#57974)

Summary:

Adds a mechanism for callers to configure `babel/plugin-transform-runtime`
programmatically via Babel caller data, in addition to preset options.

- `enableBabelRuntime` (boolean toggle, or a string to pin a specific
  `babel/runtime` version) can now be read from the Babel caller.
- `babelRuntimeModuleName` (the module helpers are imported from) can be
  provided via preset options or the Babel caller.

Both values are passed as separate primitives (Babel only permits primitive
caller values). Preset options take precedence over caller data, consistent
with how `unstable_transformProfile` is resolved.

Changelog:
[General][Added] - Allow `react-native/babel-preset` to read `enableBabelRuntime` and `babelRuntimeModuleName` from Babel caller data

Reviewed By: vzaidman

Differential Revision: D114070686
robhogan added a commit to react/metro that referenced this pull request Sep 21, 2026
…via caller

Summary:
Follow-up to 8388f71 (the default `metro:` scheme resolver), which maps `metro:babel-runtime/<path>` to metro-runtime's own `@babel/runtime` dependency. This diff is the Metro half of pointing `@babel/plugin-transform-runtime` at it.

Whenever `transformer.enableBabelRuntime` is truthy, the transform worker now passes `babelRuntimeModuleName: 'metro:babel-runtime'` to the Babel transformer, and `metro-babel-transformer` forwards it to presets as Babel caller data. Caller data reaches a preset however it's configured - including via a project `babel.config.js`, where the preset's options come from the user.

This is a no-op until a preset reads it. `@react-native/babel-preset` does from react/react-native#57974, which maps it to `@babel/plugin-transform-runtime`'s `moduleName`, so emitted helpers become `metro:babel-runtime/helpers/*` and resolve deterministically regardless of where (or whether) the project hoists `@babel/runtime`.

Changelog:
```
 - **[Feature]**: Pass `babelRuntimeModuleName: 'metro:babel-runtime'` to Babel presets via caller data when `transformer.enableBabelRuntime` is enabled
```

Test plan:
```
yarn jest packages/metro-transform-worker packages/metro-babel-transformer
yarn flow check
yarn build-ts-defs && yarn verify-api-snapshots
```
robhogan added a commit to react/metro that referenced this pull request Sep 21, 2026
…via caller

Summary:
Follow-up to 8388f71 (the default `metro:` scheme resolver), which maps `metro:babel-runtime/<path>` to metro-runtime's own `@babel/runtime` dependency. This diff is the Metro half of pointing `@babel/plugin-transform-runtime` at it.

Whenever `transformer.enableBabelRuntime` is truthy, the transform worker now passes `babelRuntimeModuleName: 'metro:babel-runtime'` to the Babel transformer, and `metro-babel-transformer` forwards it to presets as Babel caller data. Caller data reaches a preset however it's configured - including via a project `babel.config.js`, where the preset's options come from the user.

This is a no-op until a preset reads it. `@react-native/babel-preset` does from react/react-native#57974, which maps it to `@babel/plugin-transform-runtime`'s `moduleName`, so emitted helpers become `metro:babel-runtime/helpers/*` and resolve deterministically regardless of where (or whether) the project hoists `@babel/runtime`.

Changelog:
```
 - **[Feature]**: Pass `babelRuntimeModuleName: 'metro:babel-runtime'` to Babel presets via caller data when `transformer.enableBabelRuntime` is enabled
```

Test plan:
```
yarn jest packages/metro-transform-worker packages/metro-babel-transformer
yarn flow check
yarn build-ts-defs && yarn verify-api-snapshots
```
robhogan added a commit to react/metro that referenced this pull request Sep 21, 2026
…caller

Summary:
Follow-up to 8388f71 (the default `metro:` scheme resolver), which maps `metro:babel-runtime/<path>` to metro-runtime's own `@babel/runtime` dependency. This diff is the Metro half of pointing `@babel/plugin-transform-runtime` at it.

When `transformer.enableBabelRuntime` is literally `true` (the default), the transform worker passes the Babel transformer `babelRuntimeModuleName: 'metro:babel-runtime'` and `babelRuntimeVersion` - the installed version of that `@babel/runtime`. `metro-babel-transformer` forwards them to presets as Babel caller data, as `babelRuntimeModuleName` and `enableBabelRuntime` respectively, matching what `@react-native/babel-preset` reads from react/react-native#57974. Caller data reaches a preset however it's configured - including via a project `babel.config.js`, where the preset's options come from the user.

The version is read from the installed `package.json` rather than pinned to metro-runtime's range floor, so output benefits from runtime updates without a manual sync. Because that makes transform output depend on it, the `package.json` is added to the transform worker's cache key when `enableBabelRuntime` is `true`.

A string `enableBabelRuntime` keeps its current meaning (a version for the project's own `@babel/runtime`) and passes neither value. It's now documented as deprecated in favour of `true`, since a version describing the project's copy is meaningless once helpers come from Metro's.

The lookup of metro-runtime's `@babel/runtime` moves from `metroSchemeResolver` into a shared `metro/private/lib/metroBabelRuntime`, so the resolver and the worker agree on the same copy.

This is a no-op until a preset reads it.

Changelog:
```
 - **[Feature]**: When `transformer.enableBabelRuntime` is `true`, pass Metro's own `@babel/runtime` (`metro:babel-runtime`) and its installed version to Babel presets via caller data
 - **[Deprecated]**: String values of `transformer.enableBabelRuntime` (use `true`)
```

Test plan:
```
yarn jest packages/metro-transform-worker packages/metro-babel-transformer packages/metro/src/lib
yarn flow check
yarn build-ts-defs && yarn verify-api-snapshots
yarn typecheck-ts
```
robhogan added a commit to react/metro that referenced this pull request Sep 21, 2026
…caller

Summary:
Follow-up to 8388f71 (the default `metro:` scheme resolver), which maps `metro:babel-runtime/<path>` to metro-runtime's own `@babel/runtime` dependency. This diff is the Metro half of pointing `@babel/plugin-transform-runtime` at it.

When `transformer.enableBabelRuntime` is literally `true` (the default), the transform worker passes the Babel transformer `babelRuntimeModuleName: 'metro:babel-runtime'` and `babelRuntimeVersion` - the installed version of that `@babel/runtime`. `metro-babel-transformer` forwards them to presets as Babel caller data, as `babelRuntimeModuleName` and `enableBabelRuntime` respectively, matching what `@react-native/babel-preset` reads from react/react-native#57974. Caller data reaches a preset however it's configured - including via a project `babel.config.js`, where the preset's options come from the user.

The version is read from the installed `package.json` rather than pinned to metro-runtime's range floor, so output benefits from runtime updates without a manual sync. Because that makes transform output depend on it, the `package.json` is added to the transform worker's cache key when `enableBabelRuntime` is `true`.

A string `enableBabelRuntime` keeps its current meaning (a version for the project's own `@babel/runtime`) and passes neither value. It's now documented as deprecated in favour of `true`, since a version describing the project's copy is meaningless once helpers come from Metro's.

The lookup of metro-runtime's `@babel/runtime` moves from `metroSchemeResolver` into a shared `metro/private/lib/metroBabelRuntime`, so the resolver and the worker agree on the same copy.

This is a no-op until a preset reads it.

Changelog:
```
 - **[Feature]**: When `transformer.enableBabelRuntime` is `true`, pass Metro's own `@babel/runtime` (`metro:babel-runtime`) and its installed version to Babel presets via caller data
 - **[Deprecated]**: String values of `transformer.enableBabelRuntime` (use `true`)
```

Test plan:
New integration test (`integration_tests/__tests__/babel-runtime-test.js`) builds and executes a bundle through the full Metro + Babel pipeline with Metro's own `metro-babel-transformer`, and a fixture `babel.config.js` whose preset reads `@babel/runtime` configuration from caller data, as `@react-native/babel-preset` does. The fixture uses `import * as`, whose `interopRequireWildcard` helper is only available from `@babel/runtime` 7.14.0, so it's imported rather than inlined only if the installed version reaches the preset:
 - With `enableBabelRuntime: true`, the bundle imports `metro:babel-runtime/helpers/interopRequireWildcard`, which resolves to metro-runtime's own `@babel/runtime`, and executes correctly.
 - With `enableBabelRuntime: false`, the helper is inlined, and the bundle executes correctly.

```
yarn jest packages/metro/src/integration_tests packages/metro-transform-worker packages/metro-babel-transformer packages/metro/src/lib
yarn flow check
yarn build-ts-defs && yarn verify-api-snapshots
yarn typecheck-ts
```
…set (#57974)

Summary:

Adds a mechanism for callers to configure `babel/plugin-transform-runtime`
programmatically via Babel caller data, in addition to preset options.

- `enableBabelRuntime` (boolean toggle, or a string to pin a specific
  `babel/runtime` version) can now be read from the Babel caller.
- `babelRuntimeModuleName` (the module helpers are imported from) can be
  provided via preset options or the Babel caller.

Both values are passed as separate primitives (Babel only permits primitive
caller values). Preset options take precedence over caller data, consistent
with how `unstable_transformProfile` is resolved.

Changelog:
[General][Added] - Allow `react-native/babel-preset` to read `enableBabelRuntime` and `babelRuntimeModuleName` from Babel caller data

Reviewed By: vzaidman

Differential Revision: D114070686
@meta-codesync meta-codesync Bot closed this in 168a0d7 Sep 21, 2026
@meta-codesync meta-codesync Bot added the Merged This PR has been merged. label Sep 21, 2026
@meta-codesync

meta-codesync Bot commented Sep 21, 2026

Copy link
Copy Markdown

This pull request has been merged in 168a0d7.

@cortinico

Copy link
Copy Markdown
Contributor

Done 👍

@robhogan
robhogan deleted the export-D114070686 branch September 22, 2026 06:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants