webpack 核心编译器 第一节

这一节主要了描述了核心编译器的工具类方法,期中最容易理解的是 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)到缓存数据的映射。
 * 这些数据可能用于恢复模块的某些状态。
 */
相关推荐
该用户已不存在12 小时前
macOS是开发的终极进化版吗?
前端·后端
小豆包api13 小时前
小豆包AI API × Nano Banana:3D手办 + AI视频生成,「动起来」的神级玩法!
前端·api
布列瑟农的星空13 小时前
大话设计模式——观察者模式和发布/订阅模式的区别
前端·后端·架构
龙在天13 小时前
Vue3 实现 B站 视差 动画
前端
KenXu13 小时前
F2C Prompt to Design、AI 驱动的设计革命
前端
小鱼儿亮亮13 小时前
canvas中画线条,线条效果比预期宽1像素且模糊问题分析及解决方案
前端·react.js
@大迁世界13 小时前
用 popover=“hint“ 打造友好的 HTML 提示:一招让界面更“懂人”
开发语言·前端·javascript·css·html
伍哥的传说13 小时前
Tailwind CSS v4 终极指南:体验 Rust 驱动的闪电般性能与现代化 CSS 工作流
前端·css·rust·tailwindcss·tailwind css v4·lightning css·utility-first
小鱼儿亮亮13 小时前
使用Redux的combineReducers对数据拆分
前端·react.js
定栓13 小时前
Typescript入门-类型断言讲解
前端·javascript·typescript