我刚刚完成将我的 React 应用程序从 webpack 1 更新到 webpack 2。但是,我的包大小增加了约 30Kb。我希望 bundle 的大小会减小,我如何确认树摇动有效。为什么会增加?
最佳答案
TL;DR:从 2.3 版本开始,webpack 没有任何 tree shake 功能。它只是使用 UglifyJS 删除未使用的代码。
<小时/>首先我们必须定义什么是树抖动。
Stackoverflow 将其定义为“现代 JavaScript 的死代码消除算法”。
Webpack 澄清其模块系统的静态结构依赖于 ES2015 模块导入/导出。
Rollup(最初使该术语流行起来)也有类似的解释。
因此我们可以推导出一个具体的定义:静态排除未使用的 ES 模块导出。
现在,让我们看看每个模块通常有哪些转换阶段:
- babel-loader 被提供一个入口点,它是某种模块格式的 javascript 文件。 Babel 可以将其转换为另一种模块格式或保持原样 (
module: false
) - webpack 将静态解析文件并查找导入的模块(使用某种正则表达式)
- webpack 将转换模块格式(如果 babel 尚未转换)或添加一些包装器(对于 commonjs 模块)
- 导入的模块成为入口点并转到 babel-loader
- 加载并转换所有模块后,uglify 将处理结果包并删除未使用的代码 (
unused: true
)
现在,我们可以看到,虽然 uglify 可以删除未使用的导出,但它实际上并不依赖于 ES 模块语法。这只是一种通用的死代码消除,因此不能将其定义为“Tree shake”。
那么如何确认webpack是否有Tree Shaking呢?
- 首先,所有代码必须是ES模块格式。
- 正如另一个答案中已经提到的,我们必须禁用 Uglify。
- 我们还必须禁用 babel 的模块转换,因为我们无法知道该阶段是否使用了模块。
现在,如果 webpack 实际上实现了树摇算法,我们可以通过查看此入口点的包大小来确认它:
import { keyBy } from 'lodash-es'; // lodash is in ES module format
console.log(keyBy([{ key: 'value' }], 'key'));
如果 webpack 确实有 tree shake,结果应该是几十 KB。如果不是,则将是半兆字节或更多。
关于reactjs - 如何确认 Tree Shaking 是否适用于 Webpack 2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42210848/