Tree Shaking

Tree Shaking 是 ES2015 模块定义中的一个功能。它的核心点在于,在不运行模块的情况下静态地分析模块,使得 Webpack 发现哪些部分的代码正在使用,而哪些代码没有被使用。我们可以通过在未使用代码中添加一些东西来验证此行为。

webpack-common-shake 插件使得 CommonJS 模块规范在一定程度上也具备 Tree Shaking 功能。由于大多数 npm 软件包都是使用 CommonJS 模块规范编写,因此该插件很有价值。

Tree Shaking,顾名思义,把代码比作一棵树,把树上已经烂掉的果子比喻成不需要的代码,通过摇晃树的方式把烂掉的果子抖下来。

Tree Shaking 示例

要抖掉不需要的代码,您必须定义一个模块并仅使用其部分代码。定义一个:

src/shake.js

const shake = () => console.log("shake");
const bake = () => console.log("bake");

export { shake, bake };

要确保使用部分代码,请更改应用程序入口点:

src/index.js

...
import { bake } from "./shake";

bake();

...

如果你再次构建项目(npm run build)并检查构建(dist/main.js),它应该包含 console.log("bake") 但是不会包含 console.log("shake")。代码树确实已经摇过了。

为了更好地理解 Webpack 用于 Tree Shaking 的内容,请运行它 npm run build -- --display-used-exports。您将在终端看到更多的类似于 [no exports used][only some exports used: bake] 的输出结果。

如果您使用的是 terser-webpack-plugin,请启用警告来达到类似的效果。除了其他消息,你还会看到像 Dropping unused variable treeShakingDemo [./src/component.js:17,6] 这样的消息。

dead-css-loader 是一个与 CSS 模块相关的 Tree Shaking loader。

包级别上的 Tree Shaking

Tree Shaking 的概念同样适用于 ES2015 模块依赖项。鉴于包的标准语法仍然在制定,在使用这类包时必须要小心。由于这个原因,Webpack 尝试解析 package.json module 字段。

如果要使用 Webpack 这样的工具来对 npm 包应用 Tree Shaking,你应该生成一个构建,它已经转换了除 ES2015 模块定义之外的所有其他内容,然后通过 package.json module 字段指向它。在 Babel 中,您必须设置 "modules": false 从而将 ES2015 模块交给 Webpack 来处理。

为了最大限度地对外部依赖包进行 Tree Shaking,你必须使用 babel-plugin-transform-imports 重写导入,以便它们能够与 Webpack 的 tree shaking 逻辑运行一致。有关更多信息,请参阅 webpack issue#2867

SurviveJS - 构建 包括如何编写包,以便可以对它们应用 Tree shaking。

总结

Tree Shaking 是一种潜在的强大技术。为了让源代码受益于 tree shaking,必须使用 ES2015 模块语法实现 npm 包,并且必须通过 package.json module 字段暴露该模块,像 Webpack 这样的工具才能针对它应用 tree shaking。

回顾一下:

  • Tree Shaking 基于静态代码分析丢弃未使用的代码片段,Webpack 在遍历依赖关系图时为您执行此过程。
  • 要从 Tree Shaking 中受益,您必须使用 ES2015 模块语法。
  • 作为软件包作者,您可以提供包含 ES2015 模块的软件包版本,并且将其余部分也转换为 ES5。

您将在下一章学习如何使用 Webpack 管理环境变量。

用户头像
登录后发表评论