1. 嵌套 tree-shaking (Nested tree-shaking)
webpack5 可以追寻到嵌套的 exports,这可以在多次 exports 的时候提升 tree-shaking 的性能
// inner.js
export const a = 1;
export const b = 2;
// module.js
export * as inner from './inner';
// or import * as inner from './inner'; export { inner };
// user.js
import * as module from './module';
console.log(module.inner.a);
在上面这个例子中,inner 里的数据被多次 exports 了(inner.js一次,module.js一次),最终在 user.js 中使用,这时在 production 模式下,b 会被 shaking 掉。
2. 模块内部的 tree-shaking(Inner-module tree-shaking)
例如下述代码
// module.js
import { something } from './something';
function usingSomething() {
return something;
}
export function test() {
return usingSomething();
}
在 w4 的时候,w4 认为 module.js 引入了 something 并且 使用了 something,所以 something 不会被删除
当进入了 w5 时代,判断更加精确,它会监测出只有 module.js 里的 test 使用了 usingSomething 接着使用了 something。而 test、usingSomething,在 module.js 里并没有使用,而仅仅是导出出去了。也就是说,当 module.js 里的 test 未被其他文件引用时,其本身引入 something 会被删除
- 副作用 (w4 就有了)
而当 package.json 里设置 "sideEffects": false 时,判断则会更加精确,当且仅当 test 被其他文件引入并被使用时,才不会删除,否则将被『摇下来』
sideEffects 就是副作用,"sideEffects": false 则意味该包没有副作用,若没有使用,则可以删除
更详细的信息:optimization.sideEffects
3. CommonJs Tree Shaking
CommonJs 的 tree-shaking 一直是不在考虑范围之内的,因为它是动态的。但是 w5 提供了对一些 CommonJs 结构检测的支持,当 CommonJs 里的某些导出未被使用时,将被删除。并且 w5 可以通过 require() 的调用跟踪一些相关的导出变量
由于性能原因,当 w5 遇到不可分析的代码结构时,将直接终止跟踪。具体哪些代码结构可以分析,详见官网: CommonJs Tree Shaking
4. Side-Effect analysis
前面我们知道当第三方包的 package.json 设置了 "sideEffects": false, 将会将该包认为是无副作用的。
而同时,w5 也会自行分析各个包,并标记其是否是无副作用的
5. 每一次 runtime 都做优化
一个 Runtime 可以理解为一个入口(entryPoints),w5 现在默认地可以在每一次运行时都去优化模块。这可以确保每个导出的代码是真正被当前入口所需要的。
6. 整体的 tree-shaking 升级
-
w5 之前,认为
export defalut是必然会被使用的,所以不会 tree shaking 掉,但是 w5 之后,会做更优的判断其是否被使用 -
w5 会对于冲突的
export会有提示 -
es module 的动态引入
import()也将支持 tree shaking,通过使用 magic comment 可以实现,eg:/* webpackExports: ["abc", "default"] */
更多详情请关注官网:webpack.js.org/blog/2020-1…