首先看下tree-shaking的实用效果
// index.js
import {bar} from './bar';
console.log(bar);
// bar.js
export const bar = 'bar';
export const foo = 'foo';
在bar.js中导出了bar和foo两个变量,但在index.js中并没有使用foo,那么再最后的编译文件中就会把关于foo的导出和定义都会删除,其中分为了两步,第一步是把foo的导出删除
右上角就是经过标记删除后的打包代码,这时候const foo = 'foo'就变成了Dead Code,再经过Terser插件来消除Dead Code,tree-shaking功能才算完成
Dead Code 一般具有以下几个特征
•代码不会被执行,不可到达
•代码执行的结果不会被用到
•代码只会影响死变量(只写不读)
关于标记删除的一些基本原理
依赖ES Module的一些基本特性,它要求所有的导入导出语句只能出现在模块顶层,这是因为ES模块首先解析代码(并不会直接执行),其次runtime查找imports并且加载他们,最后再执行代码。这样就能进行依赖分析,分析出哪些模块被加载了,webpack会根据模块之间的依赖图判断出哪些模块被记载哪些模块没有被加载,然后就能够进行标记删除