Tree Shaking是 JavaScript 上下文中常用的术语,用于消除Dead Code(无用的代码)。利用ES6模块化规范的特性,在编译时通过静态分析代码,识别出未被使用的代码并在打包时去除。

Dead Code:比如在代码中引入了一个模块,但实际上只使用了其中的一部分代码,通过静态分析可以识别出未被使用的代码。

如何静态分析

构建工具在入口文件开始进行编译,将代码转成AST,通过分析AST形成依赖关系图,在构建依赖关系图的时候可以通过import和export确定哪些模块被导出和导入并做好标记。最后根据标记进行移除代码。经历这样一个过程后,就去除了没有用到的代码。

webpack模块关系图

注意:对于动态导入、运行时生成代码等情况,Tree shaking无法准确地识别未使用的代码。例如CommonJS支持动态加载模块,在加载前是无法确定模块是否有被调用,所以并不支持Tree Shaking。如果项目中使用了babel的话,@babel/preset-env 默认将模块转换成CommonJs语法,因此需要设置 module:false

Webpack如何开启Tree Shaking

要开启Tree Shaking,要满足以下前提:

  • 确保代码使用ES6模块化编写
  • webpack需要开启production模式

如何关闭Tree Shaking

package.jsonsideEffects默认是false,表示项目代码没有副作用,会进行Tree Shaking。我们可以手动设置为true则关闭整个项目的Tree Shaking,或者配置数组声明指定部分文件具有副作用,不要进行Tree Shaking。

{
  "name": "example-project",
  "version": "1.0.0",
  "sideEffects": [
    "./src/components/header.jsx",
    "./src/components/footer.jsx"
  ],
  "dependencies": {
    "react": "^17.0.2"
  }
}

上述表示,header.jsxfooter.jsx文件具有副作用,不要进行Tree Shaking。