tree-shaking使用注意事项
tree-shakinng基于ES6模块实现:
- 只能作为模块顶层的语句出现
- import 的模块名只能是字符串常量
- import binding 是 immutable的
ES6模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析,这就是tree-shaking的基础
所谓静态分析就是不执行代码,从字面量上对代码进行分析,ES6之前的模块化,比如我们可以动态require一个模块,只有执行后才知道引用的什么模块,这个就不能通过静态分析去做优化。
这是 ES6 modules 在设计时的一个重要考量,也是为什么没有直接采用 CommonJS,正是基于这个基础上,才使得 tree-shaking 成为可能,这也是为什么 rollup 和 webpack 2 都要用 ES6 module syntax 才能 tree-shaking
- tree-shaking对函数效果较好
- 顶层函数相对来说更容易分析,加上babel默认都是"use strict"严格模式,减少顶层函数的动态访问的方式,也更容易分析
- tree-shaking不能消除引入未使用的类定义
export default 对象被 import 后,挂在 default 上的属性和方法,即使没有被调用,也无法被 tree-shaking。
所以我们在组织模块文件时,应当尽可能避免 export default {A, B, C} 的写法
Webpack 官网提到,要开启模块的 Tree-shaking,需要满足以下四个条件:
- 使用 ES6 的 import export 语句
- 确保 ES6 模块没有被 babel 等编译器转换成 ES5 CommonJS 的形式
- 项目 package.json 文件中,要有
"sideEffects"
属性的定义(false
表示所有文件无副作用,可启用 Tree Shaking) - 使用 Webpack 的 production mode