admin管理员组

文章数量:1289558

I know ReactJS converts __DEV__ into "production" !== process.env.NODE_ENV - like this. I saw somewhere that it's converted directly to a boolean, depending on the environment, but that's another confusing point.

I was wondering, though, what specific babel-plugin/process/packages actually removes this condition from the production React (react.min.js), because there are no such conditions in that file.

From my understanding, it's a two-step process:

  1. using a Babel plugin, convert warnings and invariant calls into if ("production" !== process.env.NODE_ENV) calls
  2. remove the entire above conditions (or just its truthy branch?) in the production build, when minifying

How/where is the latter implemented?

I know ReactJS converts __DEV__ into "production" !== process.env.NODE_ENV - like this. I saw somewhere that it's converted directly to a boolean, depending on the environment, but that's another confusing point.

I was wondering, though, what specific babel-plugin/process/packages actually removes this condition from the production React (react.min.js), because there are no such conditions in that file.

From my understanding, it's a two-step process:

  1. using a Babel plugin, convert warnings and invariant calls into if ("production" !== process.env.NODE_ENV) calls
  2. remove the entire above conditions (or just its truthy branch?) in the production build, when minifying

How/where is the latter implemented?

Share Improve this question edited May 10, 2019 at 8:32 nevvermind asked May 9, 2019 at 18:56 nevvermindnevvermind 3,3922 gold badges39 silver badges45 bronze badges 3
  • @EmileBergeron If I interpret the question correctly, it is about how Facebook removes process.env.NODE_ENV checks from React's production builds – P Varga Commented May 9, 2019 at 21:20
  • 1 The term you are looking for is envify. That is, a process goes into your code and actually replaces your process.env.var expressions with its literal replacement. Then, when your code goes through minification, it removes anything that will always be true or false. There are other libraries for this too, such as loose-envify. – romellem Commented May 9, 2019 at 21:25
  • it removes anything that will always be true or false. Did you mean it removes anything that will always be false? In case it's always true, I think it only removes the condition. Cf. DefinePlugin page. – nevvermind Commented May 10, 2019 at 8:27
Add a ment  | 

2 Answers 2

Reset to default 10

ReactJS uses Webpack to bundle its production code.
Webpack has a plugin called DefinePlugin, which ReactJS uses. This plugin replaces literal values in the code, values that you can control. Very similar to piler inlining.

Either I don't get the name of this plugin, or it's just a poor choice. In my research trying to find out how ReactJS cleans up its production code, I've more than once skimmed over the new webpack.DefinePlugin() call. Also, my lack of experience with Webpack didn't help.


As mentioned in the plugin page it's a multi-step process:

1. Original code:

if (!PRODUCTION) {
  console.log('Debug info');
}

if (PRODUCTION) {
  console.log('Production log');
}

2. Inlining done by the Define plugin:

if (!true) {
  console.log('Debug info');
}
if (true) {
  console.log('Production log');
}

3. Minification step, and the final result

console.log('Production log');

The minification/optimization step is done through a tool called Terser, which is what Webpack is using. Terser looks like a fork of UglifyJS, and it, too, has the ability to remove dead code.

So it's:

  1. ReactJS pile production
  2. React configures Webpack with DefinePlugin process.env.NODE_ENV = 'production'
  3. Webpack inlining, done by the Webpack's DefinePlugin
  4. Webpack optimizing
  5. Webpack Terser plugin
  6. Terser finally removes dead code

I'd like to thank @romellem for pointing me in the right direction through this jungle.

PS: Dear future readers, I've written this in the 10th of May 2019. My findings are probably going to be obsolete soon.

The code is removed when the JS is uglified (minified).

UglifyJS2 has an option dead_code that "remove[s] unreachable code."

As to how this works, the logic here is fairly plex, but a starting point would be Uglify's eliminate_dead_code function.

本文标签: javascriptHow are the processenvNODEENV checks removed from ReactJS production buildsStack Overflow