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.json**
的**sideEffects**
默认是 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.jsx
和footer.jsx
文件具有副作用,不要进行 Tree Shaking。