webpack4 进阶篇3 ——JS tree-shaking
2019-07-04 本文已影响0人
前往悬崖下寻宝的神三算
本文长期更新,如有错误或者补充,欢迎留言 ~
关注一下不迷路 ~
tree-shaking
摇树,通过摇晃树把枯叶摇下来,代码中指去除无用的代码。
使用步骤
-
package.json
添加 sideEffects配置
"sideEffects": [
"*.css",
"*.vue" // 如果是vue项目
]
- webpack
mode
配置为production
注意:
- vue项目
由于.vue
文件混合了css(单独写没事),导致他们是有副作用的,如果tree-shaking会把css摇掉
总而言之,tree-shaking对vue项目没啥效果 -
*
检查有副作用的模块,将他们加入到sideEffects
当中
原理简述
实际上共做了2件事
1. 去除未引用ES模块变量
如果一个.js
文件,导出(export
)的变量并未被使用,则删除他们。
示例
模块a.js
中导出了2个变量square
cube
//a.js
const square = (x) => {
console.log(1111111)
return x * x;
}
const cube = (aaa) => {
console.log(2222222)
return aaa * aaa * aaa;
}
export {square, cube}
但在index.js
中引入此模块时只用到了第一个变量
//index.js
import {square} from './a.js';
console.log(square);
打包后,a.js
中的第二个变量会被删除
原理
- webpack会在打包时识别未使用的导出的变量(函数 类 对象等),将其标记为
unused harmony export xx
需要开启optimization.usedExports
- 压缩插件(TerserPlugin)对标记部分进行删除
需要开启optimization.minimize
注意:
- 如果有副作用文件需要使用package.json中的
sideEffects
配置,这需要开启optimization.sideEffects
- 未导出但内部使用了的变量不会被删除
- 即使导出的变量被其他模块导入了,但未使用,依然会被删除
- bable(7)转义并不会产生影响
2. 去除 dead code
dead code
指不执行或只定义不使用的代码
原理
压缩插件(TerserPlugin)通过遍历作用域识别这些dead code,并进行删除
示例
打包后下面的1-4都会被删除
const square = (x) => {
// 1 不执行
if (false) {
console.log(1111)
}
// 2 只定义不使用
function a() {
console.log(6666)
}
// 3 只定义不使用
var b = 2222;
return x * x;
// 4 不执行
const c = 3333;
}
答疑
-
tree-shaking
到底有啥用?
(1)针对模块缩减代码:导出的变量没被使用,那么删除这个变量
(2)针对代码块缩减代码:删除不执行或只定义不使用的代码 -
我的ui库是不是可以通过
tree-shaking
大幅度缩减代码?
并不会。
因为大多数库只是导出一个变量,当然有的支持按需引入是可以的,比如element-ui