认识
一、认识
Tree Shaking
是一个术语,通常用于描述移除 JavaScript
上下文中的未引用代码(dead-code
)。它依赖于 ES2015
模块系统中的静态结构特性,例如 import
和export
。这个术语和概念实际上是兴起于 ES2015
模块打包工具 rollup
。
Tree shaking
是基于 ES6
模板语法(import
与exports
),主要是借助ES6
模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量, 进而判断哪些模块已经加载, 哪些模块和变量未被使用或者引用,进而删除对应代码。
Tree Shaking
利用 ES6
模块的特点,只能作为模块顶层语句出现。import
的模块名只能是字符串常量。Tree Shaking
在去除冗余代码的过程中,程序会从入口文件出发,扫描所有的模块依赖,以及模块的子依赖,然后将它们链接起来形成一个抽象语法树(AST
)。随后,运行所有代码,查看哪些代码是用到过的,做好标记。最后,再将抽象语法树中没有用到的代码摇落。经历这样一个过程后,就去除了没有用到的代码。
前提是模块必须采用 ES6 Module
语法,因为 Tree Shaking
依赖 ES6
的静态语法:import
和 export
。不同于 ES6 Module
,CommonJS
支持动态加载模块,在加载前是无法确定模块是否有被调用,所以并不支持 Tree Shaking
。
二、使用
在 Webpack
中,启动 Tree Shaking
功能必须同时满足三个条件:
-
使用
ESM
规范编写模块代码 -
配置
optimization.usedExports
为true
,启动标记功能 -
启动代码优化功能,可以通过如下方式实现:
-
配置
mode = production
-
配置
optimization.minimize = true
-
提供
optimization.minimizer
数组
-
三、工作
Webpack
中,Tree-shaking
的实现,一是需要先标记出模块导出值中哪些没有被用过; 二是使用代码压缩插件 —— 如 Terser
删掉这些没被用到的导出变量。具体实现如下:
-
Webpack
构建阶段: 收集模块导出变量并记录到模块依赖关系图ModuleGraph
对象中 -
Webpack
封装阶段: 遍历所有模块,标记模块导出变量有没有被使用 -
使用代码优化插件如
Terser
,删除无效导出代码