Tree-shaking 静态分析代码, 把无用代码给删掉 什么才是无用的代码或者永不到的代码?
函数引用类型的TreeShaking
- 如果被引用的是一个纯函数, 那么当该纯函数没有被使用或引用指针没有被传递下去最终使用 就会被shaking掉
// index.js
import { funcA, funcB } from './util';
const name = funcA();
// funcB 是一个纯函数, 返回 'funcB', 给 a, 但是没有使用a
// 所以会被shaking掉
const a = funcB();
console.log(name);
// util.js
function funcA() {
return 'AAAAA';
}
function funcB() {
return '12';
}
export { funcA, funcB };
最终打包之后的结果
(() => {
'use strict';
console.log('AAAAA');
})();
// 可以看到我们的funcB 被shaking
- 如果是有副作用的函数, webpack不会shaking掉, 因为副作用函数有可能是不返回, 但是还是修改了外界的值
// index.js
import { funcA, funcB } from './util';
const name = funcA();
const a = funcB();
console.log(name);
// util.js
function funcA() {
return 'AAAAA';
}
// funcB是一个副作用函数, 他修改了外界的值
// (body.innerText)
function funcB() {
document.body.innerText = '副作用函数';
return 'BBBBB';
}
export { funcA, funcB };
打包之后的 dist/main.js:
(() =>
'use strict';
(document.body.innerText = '副作用函数'), console.log('AAAAA');
})();
可以看到如果是副作用函数, 如果使用了,那么不管返回值有没有被引用, 都会打包进来
export 方式不同, TreeShaking 不同
export default {
funcA() {
return 'AAAAA';
},
funcB() {
document.body.innerText = '副作用'; // 会被打包进去
},
};
export default {
funcA() {
return 'AAAAA';
},
funcB() {
return 'BBB'; // 没有副作用, 如果funcB 没有被引用使用, 就不会被打包进去了
},
};
打包结果:
(() => {
'use strict';
const n = {
funcA: () => 'AAAAA',
funcB() {
document.body.innerText = '123';
},
}.funcA();
console.log(n);
})();
- 另一种
export default方式
// util.js
function funcA() {
return 'AAAA';
}
// 这种方式的export 不管funcB是否副作用函数, 只要没有调用
// 就不会被打包进去
function funcB() {
document.body.innerText = '副作用';
}
export default { funcA, funcB };
打包结果:
// 调用了 funcB()
(() => {
'use strict';
const n = function () {
document.body.innerText = '123';
},
o = (function () {
return 'AAAA';
})();
n(), console.log(o);
})();
这种方式的export, 只要funcB没有被调用就不会被打包进去
总结分析:
- 从两个
export default的方式我们可以知道,export default {funcA, funcB}会export 出两个东西,n和o; export default{funcA(){}, funcB(){}}, 会明确export出一个default对象, 里面有两个属性funcA与funcB, 所以是否会打包进去, 与该属性的函数是否是一个副作用函数有关.