reactjs - 如何确认 Tree Shaking 是否适用于 Webpack 2?

标签 reactjs webpack webpack-2 tree-shaking

我刚刚完成将我的 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/

相关文章:

twitter-bootstrap - 带 bo​​otstrap.css 的 webpack 不起作用

python - 在 Next.js 中运行 python 脚本

javascript - 类型 ref 不可分配给类型 IntrinsicAttributes

reactjs - 如何使用获取 API 请求测试 Action 创建者

function - 在 Webpack 2 中传递环境变量

sass - 如何使用 Webpack 2 导入 Foundation 的 SCSS?

javascript - "The final argument passed to useEffect changed size between renders",但我不认为是这样?

angular - 从 8 : Can't resolve 'util' in '/Users/foo/node_modules/request' 更新到 Angular 11 时出错

node.js - 使用 webpack 构建 (React) 同构 web 应用程序的服务器部分,包括 CSS 样式加载器

混合js文件时laravel 'Undefined index:'