webpack 检出图 第 八 节 lib/ChunkGraph.js

🔹 ChunkGroup 相关

  • disconnectChunkGroup(chunkGroup)

    • 移除所有 block 与该 ChunkGroup 的关联。
    • 清空该 ChunkGroup 内部记录的 blocks。
    • ⚠️ 注:未来计划将 blocks 数据迁移到 ChunkGraph 统一管理。

🔹 模块 ID 操作

  • getModuleId(module)

    • 获取模块对应的 ChunkGraphModule 实例的 id
  • setModuleId(module, id)

    • 设置模块对应的 ChunkGraphModuleid 字段。

🔹 Runtime ID 操作

  • getRuntimeId(runtime)

    • 从内部 _runtimeIds Map 中获取指定 runtime 的 ID。
  • setRuntimeId(runtime, id)

    • _runtimeIds Map 中设置 runtime 与其对应的 ID。

🔹 模块哈希信息获取(内部)

  • _getModuleHashInfo(module, hashes, runtime)

    • 用于从 RuntimeSpecMap<T> 中获取对应 runtime 的哈希信息。
    • 如果 hashes 未定义,抛出错误。
    • 如果 runtime 未指定但存在多个 runtime 映射,也抛出错误。
    • 否则返回对应 runtime 的哈希信息对象。

🔹 模块哈希判断与获取

  • hasModuleHashes(module, runtime)

    • 判断模块在指定 runtime 下是否存在哈希记录。
  • getModuleHash(module, runtime)

    • 获取模块在指定 runtime 下的完整哈希值(hash 字段)。
  • getRenderedModuleHash(module, runtime)

    • 获取模块在指定 runtime 下的渲染哈希(renderedHash 字段)。

🔹 模块哈希设置

  • setModuleHashes(module, runtime, hash, renderedHash)

    • 为模块设置某个 runtime 下的 ModuleHashInfo(完整哈希和渲染哈希)。
    • 若 hashes 未初始化,则新建 RuntimeSpecMap
js 复制代码
/**
 * 断开与指定 ChunkGroup 的所有关联关系
 * @param {ChunkGroup} chunkGroup - 要断开的 ChunkGroup
 * @returns {void}
 */
disconnectChunkGroup(chunkGroup) {
	// 遍历 chunkGroup 中的所有 block
	for (const block of chunkGroup.blocksIterable) {
		// 从 block 与 chunkGroup 的映射中移除这个 block
		this._blockChunkGroups.delete(block);
	}
	// 清空 chunkGroup 自身记录的 blocks 集合
	// TODO:未来计划将 block 列表迁移至 ChunkGraph 管理
	chunkGroup._blocks.clear();
}

/**
 * 获取某个模块的 ID
 * @param {Module} module - 模块对象
 * @returns {ModuleId | null} - 返回模块 ID,可能为 null
 */
getModuleId(module) {
	// 获取该模块对应的 ChunkGraphModule 实例
	const cgm = this._getChunkGraphModule(module);
	// 返回模块 ID
	return cgm.id;
}

/**
 * 设置模块的 ID
 * @param {Module} module - 模块对象
 * @param {ModuleId} id - 要设置的 ID
 * @returns {void}
 */
setModuleId(module, id) {
	// 获取该模块对应的 ChunkGraphModule 实例
	const cgm = this._getChunkGraphModule(module);
	// 设置其 ID
	cgm.id = id;
}

/**
 * 获取某个 runtime 的 ID
 * @param {string} runtime - runtime 名称
 * @returns {string | number} - 返回该 runtime 的 ID
 */
getRuntimeId(runtime) {
	// 从内部 runtime 映射表中获取对应 ID
	return /** @type {string | number} */ (this._runtimeIds.get(runtime));
}

/**
 * 设置某个 runtime 的 ID
 * @param {string} runtime - runtime 名称
 * @param {string | number} id - 要设置的 ID
 * @returns {void}
 */
setRuntimeId(runtime, id) {
	// 设置 runtime 到 ID 的映射
	this._runtimeIds.set(runtime, id);
}

/**
 * 获取模块在某个 runtime 下的哈希信息
 * @template T
 * @param {Module} module - 模块对象
 * @param {RuntimeSpecMap<T>} hashes - 各 runtime 的哈希映射
 * @param {RuntimeSpec} runtime - 指定的 runtime
 * @returns {T} - 返回对应的哈希信息对象
 */
_getModuleHashInfo(module, hashes, runtime) {
	// 如果未设置任何哈希,抛出错误
	if (!hashes) {
		throw new Error(
			`Module ${module.identifier()} has no hash info for runtime ${runtimeToString(
				runtime
			)} (hashes not set at all)`
		);
	}
	// 如果 runtime 未指定
	else if (runtime === undefined) {
		// 将所有哈希信息收集为一个集合
		const hashInfoItems = new Set(hashes.values());
		// 若存在多个不同 runtime 的哈希信息,则无法唯一确定,抛出错误
		if (hashInfoItems.size !== 1) {
			throw new Error(
				`No unique hash info entry for unspecified runtime for ${module.identifier()} (existing runtimes: ${Array.from(
					hashes.keys(),
					r => runtimeToString(r)
				).join(", ")}).
Caller might not support runtime-dependent code generation (opt-out via optimization.usedExports: "global").`
			);
		}
		// 返回唯一的哈希信息
		return /** @type {T} */ (first(hashInfoItems));
	}
	// 如果指定了 runtime
	else {
		// 获取该 runtime 对应的哈希信息
		const hashInfo = hashes.get(runtime);
		// 若不存在,抛出错误
		if (!hashInfo) {
			throw new Error(
				`Module ${module.identifier()} has no hash info for runtime ${runtimeToString(
					runtime
				)} (available runtimes ${Array.from(
					hashes.keys(),
					runtimeToString
				).join(", ")})`
			);
		}
		// 返回找到的哈希信息
		return hashInfo;
	}
}

/**
 * 判断模块在某个 runtime 下是否有哈希信息
 * @param {Module} module - 模块对象
 * @param {RuntimeSpec} runtime - runtime 规范
 * @returns {boolean} - 是否存在哈希信息
 */
hasModuleHashes(module, runtime) {
	// 获取模块的 ChunkGraphModule 实例
	const cgm = this._getChunkGraphModule(module);
	// 取出哈希映射表
	const hashes = /** @type {RuntimeSpecMap<ModuleHashInfo>} */ (cgm.hashes);
	// 判断是否包含对应 runtime 的条目
	return hashes && hashes.has(runtime);
}

/**
 * 获取模块的完整哈希
 * @param {Module} module - 模块对象
 * @param {RuntimeSpec} runtime - runtime 规范
 * @returns {string} - 返回完整哈希值
 */
getModuleHash(module, runtime) {
	// 获取模块对应的哈希映射
	const cgm = this._getChunkGraphModule(module);
	const hashes = /** @type {RuntimeSpecMap<ModuleHashInfo>} */ (cgm.hashes);
	// 获取并返回哈希值
	return this._getModuleHashInfo(module, hashes, runtime).hash;
}

/**
 * 获取模块的渲染哈希(通常是较短的版本)
 * @param {Module} module - 模块对象
 * @param {RuntimeSpec} runtime - runtime 规范
 * @returns {string} - 返回渲染用哈希值
 */
getRenderedModuleHash(module, runtime) {
	// 获取模块的哈希映射表
	const cgm = this._getChunkGraphModule(module);
	const hashes = /** @type {RuntimeSpecMap<ModuleHashInfo>} */ (cgm.hashes);
	// 获取并返回渲染哈希
	return this._getModuleHashInfo(module, hashes, runtime).renderedHash;
}

/**
 * 设置模块在指定 runtime 下的完整哈希和渲染哈希
 * @param {Module} module - 模块对象
 * @param {RuntimeSpec} runtime - runtime 规范
 * @param {string} hash - 完整哈希值
 * @param {string} renderedHash - 渲染用哈希值
 * @returns {void}
 */
setModuleHashes(module, runtime, hash, renderedHash) {
	// 获取模块的 ChunkGraphModule 实例
	const cgm = this._getChunkGraphModule(module);
	// 若未初始化 hashes 字段,则创建新的 RuntimeSpecMap
	if (cgm.hashes === undefined) {
		cgm.hashes = new RuntimeSpecMap();
	}
	// 设置指定 runtime 的哈希值对象
	cgm.hashes.set(runtime, new ModuleHashInfo(hash, renderedHash));
}
相关推荐
iOS阿玮13 分钟前
待业的两个月,让我觉得独立开发者才是职场的归宿。
前端·app
八了个戒21 分钟前
「数据可视化 D3系列」入门第六章:比例尺的使用
前端·javascript·信息可视化·数据可视化·canvas
少糖研究所29 分钟前
ACPA算法详解
前端
Mores40 分钟前
开源 | ImageMinify:轻量级智能图片压缩工具,为你的项目瘦身加速
前端
执梦起航42 分钟前
webpack理解与使用
前端·webpack·node.js
ai大师42 分钟前
Cursor怎么使用,3分钟上手Cursor:比ChatGPT更懂需求,用聊天的方式写代码,GPT4、Claude 3.5等先进LLM辅助编程
前端
Json_1 小时前
使用vue2技术写了一个纯前端的静态网站商城-鲜花销售商城
前端·vue.js·html
1024熙1 小时前
【Qt】——理解信号与槽,学会使用connect
前端·数据库·c++·qt5
少糖研究所1 小时前
ColorThief库是如何实现图片取色的?
前端
冴羽1 小时前
SvelteKit 最新中文文档教程(22)—— 最佳实践之无障碍与 SEO
前端·javascript·svelte