如何从 ReactJS 生产版本中删除process.env.NODE_ENV检查?



我知道 ReactJS 将__DEV__转换为"production" !== process.env.NODE_ENV- 就像这样。我在某处看到它直接转换为布尔值,具体取决于环境,但这是另一个令人困惑的点。

不过,我想知道哪个特定的 babel-plugin/process/packages 实际上从生产 React中删除了这个条件 (react.min.js),因为该文件中没有这样的条件。

据我了解,这是一个两步过程:

  1. 使用 Babel 插件,将警告和固定调用转换为if ("production" !== process.env.NODE_ENV)调用
  2. 删除 在生产版本中,当最小化时,整个上述条件(或只是其真实分支?

后者是如何/在哪里实施的?

ReactJS使用Webpack来捆绑其生产代码。
Webpack 有一个名为 DefinePlugin 的插件,ReactJS 使用它。此插件替换代码中的文字值,即您可以控制的值。与编译器内联非常相似。

要么我没有得到这个插件的名字,要么它只是一个糟糕的选择。在我的研究中,试图找出 ReactJS 如何清理其生产代码,我不止一次浏览了new webpack.DefinePlugin()调用。此外,我缺乏 Webpack 的经验也无济于事。


如插件页面所述,这是一个多步骤的过程:

1. 原始代码

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

2. 由定义插件完成的内联

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

3.缩小步骤和最终结果

console.log('Production log');

缩小/优化步骤是通过一个名为 Terser的工具完成的,这是 Webpack 正在使用的。Terser看起来像UglifyJS的一个分支,它也有能力删除死代码。

所以它是:

  1. ReactJS 编译生产
  2. React 使用DefinePlugin process.env.NODE_ENV = 'production'配置 Webpack
  3. Webpack 内联,由 Webpack 的DefinePlugin完成
  4. 网络包优化
  5. Webpack Terser 插件
  6. Terser 最终删除了死代码

我要感谢@romellem在这片丛林中为我指明了正确的方向。

PS:亲爱的未来读者,我在2019年5月10日写了这篇文章。我的发现可能很快就会过时。

当 JS 被丑化(缩小)时,代码被删除。

UglifyJS2 有一个选项dead_code">删除无法访问的代码"。

至于它是如何工作的,这里的逻辑相当复杂,但一个起点是Uglify的eliminate_dead_code函数。

最新更新