这一节主要了描述了核心编译器的工具类方法,期中最容易理解的是 unsafeCacheData 存储依赖到模块的映射
js
/**
* @typedef {object} KnownCreateStatsOptionsContext
* @property {boolean=} forToString
*/
/** @typedef {Record<string, any> & KnownCreateStatsOptionsContext} CreateStatsOptionsContext */
/**
* CreateStatsOptionsContext 是一个类型定义,表示一个对象,
* 该对象既包含字符串键的任意值,也包括 KnownCreateStatsOptionsContext 的所有属性。
*/
/** @typedef {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} CodeGenerationJobs */
/**
* CodeGenerationJobs 是一个类型定义,表示一个数组,每个元素是一个对象,
* 该对象包含:
* - module: Module 类型,表示 Webpack 处理的模块
* - hash: string 类型,该模块的哈希值
* - runtime: RuntimeSpec 类型,代表当前模块的运行时环境
* - runtimes: RuntimeSpec[] 类型,该模块支持的多个运行时环境
*/
/** @typedef {{javascript: ModuleTemplate}} ModuleTemplates */
/**
* ModuleTemplates 是一个类型定义,表示一个对象,该对象包含:
* - javascript: ModuleTemplate 类型,代表 JavaScript 模块的模板
*/
/** @typedef {Set<Module>} NotCodeGeneratedModules */
/**
* NotCodeGeneratedModules 是一个类型定义,表示一个 Set 集合,
* 其中包含所有未进行代码生成的模块(Module)。
*/
/** @type {AssetInfo} */
const EMPTY_ASSET_INFO = Object.freeze({});
/**
* EMPTY_ASSET_INFO 是一个常量,表示空的资源信息对象。
* 通过 Object.freeze 使其不可修改,以确保 Webpack 在运行时不会意外更改该对象。
*/
const esmDependencyCategory = "esm";
/**
* esmDependencyCategory 是一个字符串常量,表示 ES 模块(ESM)类型的依赖类别。
*/
// TODO webpack 6: remove
/**
* @deprecated
* 这是一个用于获取 Webpack `Compilation` 的 `normalModuleLoader` 钩子的函数。
* Webpack 6 计划移除该钩子,官方建议改用 `NormalModule.getCompilationHooks(compilation).loader`。
*
* @param {Compilation} compilation Webpack 编译对象
* @returns {NormalModuleCompilationHooks["loader"]} hooks 相关钩子
*/
const deprecatedNormalModuleLoaderHook = util.deprecate(
compilation =>
require("./NormalModule").getCompilationHooks(compilation).loader,
"Compilation.hooks.normalModuleLoader was moved to NormalModule.getCompilationHooks(compilation).loader",
"DEP_WEBPACK_COMPILATION_NORMAL_MODULE_LOADER_HOOK"
);
// TODO webpack 6: remove
/**
* 该函数用于定义已被移除的 `moduleTemplates` 属性(`asset` 和 `webassembly`)。
* 调用这些属性会抛出错误,以告知用户这些功能已被删除。
*
* @param {ModuleTemplates | undefined} moduleTemplates 需要修改的模块模板对象
*/
const defineRemovedModuleTemplates = moduleTemplates => {
Object.defineProperties(moduleTemplates, {
asset: {
enumerable: false, // 不会出现在 Object.keys() 或 for...in 遍历中
configurable: false, // 不能删除或重新定义
get: () => {
throw new WebpackError(
"Compilation.moduleTemplates.asset has been removed"
);
}
},
webassembly: {
enumerable: false,
configurable: false,
get: () => {
throw new WebpackError(
"Compilation.moduleTemplates.webassembly has been removed"
);
}
}
});
moduleTemplates = undefined; // 清空 moduleTemplates 变量
};
/**
* 定义 ID 比较器,按 `id` 排序。
*/
const byId = compareSelect(c => c.id, compareIds);
/**
* 定义 Name 或 Hash 比较器,按 `name` 先排序,如果 `name` 相同,则按 `fullHash` 排序。
*/
const byNameOrHash = concatComparators(
compareSelect(c => c.name, compareIds),
compareSelect(c => c.fullHash, compareIds)
);
/**
* 定义错误信息比较器,按 `message` 排序。
*/
const byMessage = compareSelect(err => `${err.message}`, compareStringsNumeric);
/**
* 定义模块比较器,按模块的 `identifier()` 进行排序。
*/
const byModule = compareSelect(
err => (err.module && err.module.identifier()) || "",
compareStringsNumeric
);
/**
* 定义错误位置比较器,按 `loc` 进行排序(loc 代表错误发生的位置)。
*/
const byLocation = compareSelect(err => err.loc, compareLocations);
/**
* 组合多个错误比较器:
* 1. 先按 `module` 排序
* 2. 再按 `location` 排序
* 3. 最后按 `message` 排序
*/
const compareErrors = concatComparators(byModule, byLocation, byMessage);
/** @type {WeakMap<Dependency, Module & { restoreFromUnsafeCache: Function } | null>} */
const unsafeCacheDependencies = new WeakMap();
/**
* unsafeCacheDependencies 是一个 WeakMap,存储依赖(Dependency)到模块(Module)的映射。
* 其中,模块包含 `restoreFromUnsafeCache` 方法。
* 这个映射用于缓存模块,但 Webpack 可能会在未来移除该机制。
*/
/** @type {WeakMap<Module & { restoreFromUnsafeCache: Function }, object>} */
const unsafeCacheData = new WeakMap();
/**
* unsafeCacheData 是一个 WeakMap,存储模块(Module)到缓存数据的映射。
* 这些数据可能用于恢复模块的某些状态。
*/