之所以写这篇文章,是因为前几天被一个标题党给骗了,开头写的多高级说是大厂面试官问起tree sharking的原理,面试者回答不上,然后就解答了这个原理,还引起我的好奇心,就读了下去,最后结论简单来说1.要用es6 2.webpack是通过ast解析来完成的,读完之后我觉得自己被骗了,写的什么东西啊。
然后我自己去读了下代码,算是简单了解了webpack的加入unused harmony export注释的原理,然后彻底删除是压缩插件来做的。
FlagDependencyUsagePlugin
这个插件就是用来检测module有哪些export使用了。以下代码都是精简过的
// 从入口文件开始一级一级去解析每个module,preparedEntrypoint.module是入口module
for (const preparedEntrypoint of compilation._preparedEntrypoints) {
if (preparedEntrypoint.module) {
processModule(preparedEntrypoint.module, true);
}
}
// 在这里把每个module有哪些依赖给遍历一下,筛选出import类型的依赖
for (const dep of depBlock.dependencies) {
// 这个module是使用import的module
const reference = compilation.getDependencyReference(module, dep);
if (!reference) return;
const referenceModule = reference.module;
const importedNames = reference.importedNames;
const oldUsed = referenceModule.used;
const oldUsedExports = referenceModule.usedExports;
if (
!oldUsed ||
(importedNames &&
(!oldUsedExports || !isSubset(oldUsedExports, importedNames)))
) {
// 如果找到了那么给这个引用module打上使用标签,importedNames就是引用的名字 比如import { mul } from './ddd';
// 那importedNames就是 mul
processModule(referenceModule, importedNames);
}
}
// 最后一步就是 给被使用的module加一个标识符,然后这个插件的任务就完成了
module.usedExports = importedNames
// 在转换为真实文件的时候,获取module的所有HarmonyExportSpecifierDependency的依赖,简单说就是export依赖
// 比如说export了2个函数mul 和 feq,那么会有2个export依赖
// dep.name 就是mul这个函数名,然后判断在这个module的usedExports数组是否有这个名字就决定是否加unused harmony export注释
dep.originModule.isUsed(dep.name)
自己去读了下代码,至少比有一些博人眼球的文章要深入一点