Babel preset: don't override dev based on omission of redundant withDevTools, infer from env() instead.#55805
Closed
Babel preset: don't override dev based on omission of redundant withDevTools, infer from env() instead.#55805
dev based on omission of redundant withDevTools, infer from env() instead.#55805Conversation
…thDevTools`, infer from `env()` instead.
Summary:
Currently the RN Babel preset has this surprising bit of behaviour:
```js
module.exports = (options, babel) => {
if (options.withDevTools == null) {
const env = process.env.BABEL_ENV || process.env.NODE_ENV;
if (!env || env === 'development') {
return getPreset(null, {...options, dev: true}, babel);
}
}
return getPreset(null, options, babel);
};
```
If the (undocumented, otherwise unused) `withDevTools` option is set (to anything), we will override any given value of `dev` to `true` if `BABEL_ENV` || `NODE_ENV || 'development' === 'development'`.
To put that another way, with `NODE_ENV=development` and `BABEL_ENV` unset, we would always produce a dev bundle even if `{ dev: false }`
Expo sets `withDevTools: false` to stop this happening, and always set `dev` (so this diff means **no observable change under Expo**):
https://github.com/expo/expo/blob/4a46dbff7a5a77d9fe06d30a70d7fab38cfc7f9a/packages/babel-preset-expo/build/index.js#L235-L236
This odd-looking override was introduced in 2017 in bc22a4d / D5237158 as a way to gate `babel/plugin-transform-react-jsx-source`, *before the preset accepted any other options* - it was never intended to override `dev`. Now, we gate that same plugin under `options.dev`.
## Inferring `dev` when unspecified
The one potentially load-bearing piece of this is that, when a consumer specifies neither `withDevTools` nor `dev` (or maybe no options at all), this code serves to infer it from `process.env.BABEL_ENV || process.env.NODE_ENV`, which is reasonable and actually closer to the way typical plugins/presets work, but a better mechanism is to use the `env()` API (which defaults to `process.env.BABEL_ENV || process.env.NODE_ENV`).
https://babeljs.io/docs/config-files#apienv
## This change
- Removes the obsolete use of `withDevToolss`, and never overrides the explicitly-passed `dev`
- Where `dev` is not specified, falls back to the Babel environment.
Changelog:
[General][Fixed] Babel-preset: Don't override explicitly-passed `dev` config if obsolete `withDevTools` is missing
Differential Revision: D94660480
meta-codesync bot
pushed a commit
that referenced
this pull request
Feb 27, 2026
…hDevTools`, infer from `env()` instead. (#55805) Summary: Currently the RN Babel preset has this surprising bit of behaviour: ```js module.exports = (options, babel) => { if (options.withDevTools == null) { const env = process.env.BABEL_ENV || process.env.NODE_ENV; if (!env || env === 'development') { return getPreset(null, {...options, dev: true}, babel); } } return getPreset(null, options, babel); }; ``` If the (undocumented, otherwise unused) `withDevTools` option is set (to anything), we will override any given value of `dev` to `true` if `BABEL_ENV` || `NODE_ENV || 'development' === 'development'`. To put that another way, with `NODE_ENV=development` and `BABEL_ENV` unset, we would always produce a dev bundle even if `{ dev: false }` Expo sets `withDevTools: false` to stop this happening, and always set `dev` (so this diff means **no observable change under Expo**): https://github.com/expo/expo/blob/4a46dbff7a5a77d9fe06d30a70d7fab38cfc7f9a/packages/babel-preset-expo/build/index.js#L235-L236 This odd-looking override was introduced in 2017 in bc22a4d / D5237158 as a way to gate `babel/plugin-transform-react-jsx-source`, *before the preset accepted any other options* - it was never intended to override `dev`. Now, we gate that same plugin under `options.dev`. ## Inferring `dev` when unspecified The one potentially load-bearing piece of this is that, when a consumer specifies neither `withDevTools` nor `dev` (or maybe no options at all), this code serves to infer it from `process.env.BABEL_ENV || process.env.NODE_ENV`, which is reasonable and actually closer to the way typical plugins/presets work, but a better mechanism compatible with Babel's cache is to use the `env()` API (which defaults to `process.env.BABEL_ENV || process.env.NODE_ENV`, so preserves behaviour). https://babeljs.io/docs/config-files#apienv ## This change - Removes the obsolete use of `withDevToolss`, and never overrides the explicitly-passed `dev` - Where `dev` is not specified, falls back to the Babel environment. Changelog: [General][Fixed] Babel-preset: Don't override explicitly-passed `dev` config if obsolete `withDevTools` is missing Reviewed By: huntie Differential Revision: D94660480
meta-codesync bot
pushed a commit
that referenced
this pull request
Feb 27, 2026
…t mutate `process.env.BABEL_ENV` Summary: After #55805, the RN Babel preset no longer reads `process.env.BABEL_ENV` directly, instead using Babel's `env()` API, which is both cache-aware and properly respects explicit `envName` config. See: - https://babeljs.io/docs/config-files#apienv - https://babeljs.io/docs/options#envname Now, instead of mutating `process.env.BABEL_ENV` to force the environment for a transform, we can specify `envName` instead. Changelog: [Internal] Differential Revision: D94662935
|
This pull request has been merged in c5a38ab. |
meta-codesync bot
pushed a commit
that referenced
this pull request
Mar 2, 2026
…t mutate `process.env.BABEL_ENV` (#55806) Summary: After #55805, the RN Babel preset no longer reads `process.env.BABEL_ENV` directly, instead using Babel's `env()` API, which is both cache-aware and properly respects explicit `envName` config. See: - https://babeljs.io/docs/config-files#apienv - https://babeljs.io/docs/options#envname Now, instead of mutating `process.env.BABEL_ENV` to force the environment for a transform (and having to worry about restoring it to avoid side-effects), we can just specify `envName` instead. Changelog: [Internal] Reviewed By: javache Differential Revision: D94662935
meta-codesync bot
pushed a commit
that referenced
this pull request
Mar 2, 2026
…t mutate `process.env.BABEL_ENV` (#55806) Summary: Pull Request resolved: #55806 After #55805, the RN Babel preset no longer reads `process.env.BABEL_ENV` directly, instead using Babel's `env()` API, which is both cache-aware and properly respects explicit `envName` config. See: - https://babeljs.io/docs/config-files#apienv - https://babeljs.io/docs/options#envname Now, instead of mutating `process.env.BABEL_ENV` to force the environment for a transform (and having to worry about restoring it to avoid side-effects), we can just specify `envName` instead. Changelog: [Internal] Reviewed By: javache Differential Revision: D94662935 fbshipit-source-id: 598a8dd53e33e4b5edfe62778a61c6bf3c48a4e7
zoontek
pushed a commit
to zoontek/react-native
that referenced
this pull request
Mar 9, 2026
…hDevTools`, infer from `env()` instead. (facebook#55805) Summary: Pull request resolved: facebook#55805 Currently the RN Babel preset has this surprising bit of behaviour: ```js module.exports = (options, babel) => { if (options.withDevTools == null) { const env = process.env.BABEL_ENV || process.env.NODE_ENV; if (!env || env === 'development') { return getPreset(null, {...options, dev: true}, babel); } } return getPreset(null, options, babel); }; ``` If the (undocumented, otherwise unused) `withDevTools` option is set (to anything), we will override any given value of `dev` to `true` if `BABEL_ENV` || `NODE_ENV || 'development' === 'development'`. To put that another way, with `NODE_ENV=development` and `BABEL_ENV` unset, we would always produce a dev bundle even if `{ dev: false }` Expo sets `withDevTools: false` to stop this happening, and always set `dev` (so this diff means **no observable change under Expo**): https://github.com/expo/expo/blob/4a46dbff7a5a77d9fe06d30a70d7fab38cfc7f9a/packages/babel-preset-expo/build/index.js#L235-L236 This odd-looking override was introduced in 2017 in facebook@bc22a4d / D5237158 as a way to gate `babel/plugin-transform-react-jsx-source`, *before the preset accepted any other options* - it was never intended to override `dev`. Now, we gate that same plugin under `options.dev`. ## Inferring `dev` when unspecified The one potentially load-bearing piece of this is that, when a consumer specifies neither `withDevTools` nor `dev` (or maybe no options at all), this code serves to infer it from `process.env.BABEL_ENV || process.env.NODE_ENV`, which is reasonable and actually closer to the way typical plugins/presets work, but a better mechanism compatible with Babel's cache is to use the `env()` API (which defaults to `process.env.BABEL_ENV || process.env.NODE_ENV`, so preserves behaviour). https://babeljs.io/docs/config-files#apienv ## This change - Removes the obsolete use of `withDevToolss`, and never overrides the explicitly-passed `dev` - Where `dev` is not specified, falls back to the Babel environment. Changelog: [General][Fixed] Babel-preset: Don't override explicitly-passed `dev` config if obsolete `withDevTools` is missing Reviewed By: huntie Differential Revision: D94660480 fbshipit-source-id: 5dfae8fb704e6881b03120cd14510795382a98ba
zoontek
pushed a commit
to zoontek/react-native
that referenced
this pull request
Mar 9, 2026
…t mutate `process.env.BABEL_ENV` (facebook#55806) Summary: Pull Request resolved: facebook#55806 After facebook#55805, the RN Babel preset no longer reads `process.env.BABEL_ENV` directly, instead using Babel's `env()` API, which is both cache-aware and properly respects explicit `envName` config. See: - https://babeljs.io/docs/config-files#apienv - https://babeljs.io/docs/options#envname Now, instead of mutating `process.env.BABEL_ENV` to force the environment for a transform (and having to worry about restoring it to avoid side-effects), we can just specify `envName` instead. Changelog: [Internal] Reviewed By: javache Differential Revision: D94662935 fbshipit-source-id: 598a8dd53e33e4b5edfe62778a61c6bf3c48a4e7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Currently the RN Babel preset has this surprising bit of behaviour:
If the (undocumented, otherwise unused)
withDevToolsoption is set (to anything), we will override any given value ofdevtotrueifBABEL_ENV||NODE_ENV || 'development' === 'development'.To put that another way, with
NODE_ENV=developmentandBABEL_ENVunset, we would always produce a dev bundle even if{ dev: false }Expo sets
withDevTools: falseto stop this happening, and always setdev(so this diff means no observable change under Expo):https://github.com/expo/expo/blob/4a46dbff7a5a77d9fe06d30a70d7fab38cfc7f9a/packages/babel-preset-expo/build/index.js#L235-L236
This odd-looking override was introduced in 2017 in bc22a4d / D5237158 as a way to gate
babel/plugin-transform-react-jsx-source, before the preset accepted any other options - it was never intended to overridedev. Now, we gate that same plugin underoptions.dev.Inferring
devwhen unspecifiedThe one potentially load-bearing piece of this is that, when a consumer specifies neither
withDevToolsnordev(or maybe no options at all), this code serves to infer it fromprocess.env.BABEL_ENV || process.env.NODE_ENV, which is reasonable and actually closer to the way typical plugins/presets work, but a better mechanism is to use theenv()API (which defaults toprocess.env.BABEL_ENV || process.env.NODE_ENV).https://babeljs.io/docs/config-files#apienv
This change
withDevToolss, and never overrides the explicitly-passeddevdevis not specified, falls back to the Babel environment.Changelog:
[General][Fixed] Babel-preset: Don't override explicitly-passed
devconfig if obsoletewithDevToolsis missingDifferential Revision: D94660480