0 省流结论
webpack5 支持了对Commonjs的tree-shaking,依据见文档
省流贴图
1 前情提要
在某平台买了webpack5学习资料,发现tree-shaking章节和文档冲突,因为很尊重作者(ta的webpack文章水平有一说一的质量好)然后自己做了小demo验证了下
2 验证过程
foo.js文件
const testCommon1 = 'abcs'
const testCommon2 = '2333'
module.exports.a = testCommon1
module.exports.c = testCommon2
index.js文件
import { test1,test2 } from './esm.js'
let a = require('./foo.js').a
console.log(test1,a)
webpack.config.js
const path = require("path");
debugger
module.exports = {
entry: "./index.js",
devtool: false,
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
clean: true,
},
// mode:'production',
mode: "development",
optimization: {
usedExports: true,
},
};
分析bundle.js产物得出webpack内部会对未使用的导出做了处理,即标记 __webpack_unuesed_export __ 现阶段webpack内部对commonjs的tree-shaking大家可以理解为不那么彻底的“tree-shaking”
因为对于esm其实webpack是有 harmony 处理,后面有时间会出两者的内部区别
/***/ "./foo.js":
/*!****************!*\
!*** ./foo.js ***!
\****************/
/***/ ((module) => {
var __webpack_unused_export__;
const testCommon1 = 'abcs'
const testCommon2 = '2333'
module.exports.a = testCommon1
__webpack_unused_export__ = testCommon2
/***/ })
3 追溯源码
目录位置 webpack-main/lib/dependencies/CommonJsExportsDependency.js
主要函数片段,贴图如下
这里着重介绍一下InitFragments对象, 它是之前webpack版本DependenciesBlockVariables中的替代品。
官网中单纯介绍它为可以删除重复数据,实际上它做的东西很多,比如基于esm的tree-shaking有着harmony 处理,深扒出 在harmony中核心对象HarmonyExportInitFragment是基于InitFragments,来做无效代码的删除
4 总结之外的东西
在当今前端世界中 构建打包编译工具层出不穷,变着花样惹人眼的时候,也有老伙伴默默的给你升级套餐,比如webpack5有很多值得bb的点,比如长期缓存,原生worker的支持,模块联邦等等。