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

  1. tree-shaking对函数效果较好
  2. 顶层函数相对来说更容易分析,加上babel默认都是"use strict"严格模式,减少顶层函数的动态访问的方式,也更容易分析
  3. tree-shaking不能消除引入未使用的类定义

export default 对象被 import 后,挂在 default 上的属性和方法,即使没有被调用,也无法被 tree-shaking。

所以我们在组织模块文件时,应当尽可能避免 export default {A, B, C} 的写法

Webpack 官网提到,要开启模块的 Tree-shaking,需要满足以下四个条件

  1. 使用 ES6 的 import export 语句
  2. 确保 ES6 模块没有被 babel 等编译器转换成 ES5 CommonJS 的形式
  3. 项目 package.json 文件中,要有 "sideEffects" 属性的定义(false 表示所有文件无副作用,可启用 Tree Shaking)
  4. 使用 Webpack 的 production mode