如何确认树摇动是否与Webpack 2一起使用?

时间:2017-02-13 18:20:40

标签: reactjs webpack webpack-2 tree-shaking

我刚刚将我的反应应用程序从webpack 1更新到webpack 2.然而,我的捆绑包大小增加了~30Kb。我希望捆绑的大小会减少,我怎么能确认树摇动的效果。为什么增加?

2 个答案:

答案 0 :(得分:3)

TL; DR:从版本2.3开始,webpack没有任何树摇动。它只使用UglifyJS来删除未使用的代码。

首先,我们必须定义什么是树摇动。

  • Stackoverflow将其定义为"用于现代javascript的死代码消除算法"。

  • Webpack澄清它依赖于ES2015模块导入/导出其模块系统的静态结构。

  • Rollup(最初推广该术语)也有类似的解释。

因此,我们可以推导出一个特定的定义:静态排除未使用的ES模块导出。

现在,让我们看看每个模块通常具有哪些转换阶段:

  • babel-loader被输入一个入口点,这是一个模块格式的javascript文件。 Babel可以将其转换为另一种模块格式,保持原样(module: false
  • webpack将静态解析文件并查找导入的模块(使用某种regexp)
  • webpack将转换模块格式(如果babel没有转换它)或添加一些包装器(用于commonjs模块)
  • 导入的模块成为入口点并转到babel-loader
  • 在加载和转换所有模块之后,uglify将处理结果bunle并删除未使用的代码(unused: true

现在,我们可以看到虽然uglify可以删除未使用的导出,但它实际上并不依赖于ES模块语法。它只是一个通用的死代码消除因此它不能被定义为"树摇动"。

那么我们怎样才能确定webpack是否有树摇动?

  • 首先,所有代码必须采用ES模块格式。
  • 正如在另一个答案中已经提到的那样,我们必须禁用Uglify。
  • 我们还必须禁用babel模块转换,因为我们无法知道该阶段是否使用了模块。

现在如果webpack实际上实现了树摇动算法,我们可以通过查看此入口点的包大小来确认它:

import { keyBy } from 'lodash-es'; // lodash is in ES module format

console.log(keyBy([{ key: 'value' }], 'key'));

如果webpack确实有树摇动,结果应该是几十千字节。如果它不是半兆字节或更多。

答案 1 :(得分:1)

您可以采取以下几个步骤:

  1. 关闭minification / uglify
  2. 在您知道未使用的某些功能中插入注释
  3. 检查输出以查看是否存在这些评论
  4. Webpack还可以显示每个导入模块/包的大小。例如,在工作中我们有一个包含lodash和下划线的包,因为我们正在使用的库之一需要每个库; webpack清楚地显示了每个包添加了多少千字节:

    webpack bundle sizes for lodash and underscore

    你应该可以从中看到尺寸增加的来源。