引入
了解Tree Shaking之前先来看一个例子:
math.js:
export const add = (a, b) => {
console.log(a+b);
}
export const minus = (a, b) => {
console.log(a-b);
}
index.js:
import { add } from './math';
add(1, 2);
若在development
模式下打包文件,可以发现虽然我们只从math.js
引入了add
这个方法,但是打包出的文件中依旧是两个方法都有。
这就引发了我们的思考,由于一个模块中可能会导出许多的方法、属性。如果我们只打包我们所需要的那部分代码不就可以大幅精简打包文件了吗?
是的,这个过程就是Tree Shaking,直译过来就是摇树,就是将多余的枝干摇落。
使用
首先如果是在production
的模式下进行打包,那么默认就会进行Tree Shaking,若是在development
模式下,则需要在配置文件中进行如下配置:
{
...,
optimization: {
usedExports: true
}
}
不过呢在development
模式下即便是进行了如上配置,打包出的文件也依然会包含模块的所有代码。仅仅是在注释中做出了标注
这时因为若在开发环境中去掉某些代码,在出现错误时就无法正确体现代码的行数。
注:Tree Shaking仅支持ES module(即通过import引入的module)
问题
Tree Shaking是通过查看我们用import
引入的模块有没有导出方法或属性以及我们使用了哪些导出的内容来判断是否进行Tree Shaking。
那这样就会有一个问题,那便是例如@babel/polyfill
这样的库,它并没有导出任何的内容,它是将方法挂载到了window
对象上。
同样的,还有CSS文件,它也没有导出任何的内容。
那么Tree Shaking默认的情况下,这些文件通通不会被打包。
那么该怎么办呢?
这时我们需要在package.json
中设置“sideEffects”字段,字段的值是布尔值或者一个数组,数组元素即为不需要Tree Shaking的模块名或文件路径。若设置为false
,则代表所有文件都会经过Tree Shaking过程。