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

🔧 Chunk 与 Entry Module 的连接管理

  • disconnectEntryModule(module)

    • 移除某模块在所有 chunk 中的 entry 角色。
    • 清除该模块记录的 entryInChunks
  • disconnectEntries(chunk)

    • 将指定 chunk 的所有 entry 模块解绑。
    • 更新对应模块的 entryInChunks,若为空则置为 undefined

🔢 Entry / Runtime Module 数量查询

  • getNumberOfEntryModules(chunk)

    • 获取 chunk 中的 entry 模块数量。
  • getNumberOfRuntimeModules(chunk)

    • 获取 chunk 中 runtime 模块的数量。

🔁 获取 chunk 中的模块集合(entry/runtime/hash)

  • getChunkEntryModulesIterable(chunk)

    • 返回 chunk 中所有 entry 模块(可迭代,不可修改)。
  • getChunkRuntimeModulesIterable(chunk)

    • 返回 chunk 中所有 runtime 模块(可迭代,不可修改)。
  • getChunkRuntimeModulesInOrder(chunk)

    • 返回按执行顺序排序的 runtime 模块数组。
  • getChunkFullHashModulesIterable(chunk)

    • 获取参与 chunk full hash 计算的模块(可迭代)。
  • getChunkFullHashModulesSet(chunk)

    • 获取参与 chunk full hash 计算的模块集合(只读)。
  • getChunkDependentHashModulesIterable(chunk)

    • 获取参与 dependent hash 的模块(可迭代)。
  • getChunkEntryModulesWithChunkGroupIterable(chunk)

    • 获取 chunk 中的 entry 模块及其对应 chunkGroup 信息。

🔁 Chunk 依赖关系管理(与其他 chunk 的关系)

  • getChunkEntryDependentChunksIterable(chunk)

    • 获取同一 entrypoint 下与该 chunk 相关但无 runtime 的 chunk。
  • hasChunkEntryDependentChunks(chunk)

    • 判断 chunk 是否还有 entryGroup 中的其他 chunk 存在依赖。

🔗 Async Block 与 ChunkGroup 映射关系

  • getBlockChunkGroup(depBlock)

    • 获取异步依赖块对应的 chunkGroup。
  • connectBlockAndChunkGroup(depBlock, chunkGroup)

    • 建立异步依赖块和 chunkGroup 的映射关系。
js 复制代码
/**
 * 断开某个模块与所有 chunk 的 entry 关系(该模块将不再作为 entry module 存在)
 * @param {Module} module the entry module, it will no longer be entry
 * @returns {void}
 */
disconnectEntryModule(module) {
	const cgm = this._getChunkGraphModule(module); // 获取模块的 ChunkGraphModule 实例
	for (const chunk of /** @type {EntryInChunks} */ (cgm.entryInChunks)) {
		const cgc = this._getChunkGraphChunk(chunk); // 获取 chunk 的 ChunkGraphChunk 实例
		cgc.entryModules.delete(module); // 从该 chunk 的 entryModules 中删除该模块
	}
	cgm.entryInChunks = undefined; // 清除模块记录的所有 entry 关联
}

/**
 * 将某个 chunk 的所有 entry module 全部断开
 * @param {Chunk} chunk the chunk, for which all entries will be removed
 * @returns {void}
 */
disconnectEntries(chunk) {
	const cgc = this._getChunkGraphChunk(chunk); // 获取 chunk 的 ChunkGraphChunk 实例
	for (const module of cgc.entryModules.keys()) {
		const cgm = this._getChunkGraphModule(module); // 获取模块的 ChunkGraphModule 实例
		(cgm.entryInChunks).delete(chunk); // 从模块的 entryInChunks 中删除该 chunk
		if ((cgm.entryInChunks).size === 0) {
			cgm.entryInChunks = undefined; // 若没有任何 chunk 关联,清除 entryInChunks
		}
	}
	cgc.entryModules.clear(); // 清除 chunk 上所有 entry 模块
}

/**
 * 获取 chunk 中的 entry 模块数量
 * @param {Chunk} chunk the chunk
 * @returns {number} the amount of entry modules in chunk
 */
getNumberOfEntryModules(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	return cgc.entryModules.size;
}

/**
 * 获取 chunk 中的 runtime 模块数量
 * @param {Chunk} chunk the chunk
 * @returns {number} the amount of runtime modules in chunk
 */
getNumberOfRuntimeModules(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	return cgc.runtimeModules.size;
}

/**
 * 获取 chunk 中的所有 entry 模块(返回可迭代对象)
 * @param {Chunk} chunk the chunk
 * @returns {Iterable<Module>} iterable of modules (do not modify)
 */
getChunkEntryModulesIterable(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	return cgc.entryModules.keys();
}

/**
 * 获取 chunk 所依赖的其他 chunk(同一个 entryPoint 下但非 runtime chunk)
 * @param {Chunk} chunk the chunk
 * @returns {Iterable<Chunk>} iterable of chunks
 */
getChunkEntryDependentChunksIterable(chunk) {
	const set = new Set(); // 用于收集依赖的 chunk
	for (const chunkGroup of chunk.groupsIterable) {
		if (chunkGroup instanceof Entrypoint) {
			const entrypointChunk = chunkGroup.getEntrypointChunk(); // 获取入口 chunk
			const cgc = this._getChunkGraphChunk(entrypointChunk);
			for (const chunkGroup of cgc.entryModules.values()) {
				for (const c of chunkGroup.chunks) {
					if (c !== chunk && c !== entrypointChunk && !c.hasRuntime()) {
						set.add(c); // 添加非本身、非入口且不包含 runtime 的 chunk
					}
				}
			}
		}
	}
	return set;
}

/**
 * 判断该 chunk 是否有依赖的 chunk(entry 模块所在 chunkGroup 中存在其他 chunk)
 * @param {Chunk} chunk the chunk
 * @returns {boolean} true, when it has dependent chunks
 */
hasChunkEntryDependentChunks(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	for (const chunkGroup of cgc.entryModules.values()) {
		for (const c of chunkGroup.chunks) {
			if (c !== chunk) return true; // 存在其他 chunk 即返回 true
		}
	}
	return false;
}

/**
 * 获取 chunk 中的所有 runtime 模块(返回可迭代对象)
 * @param {Chunk} chunk the chunk
 * @returns {Iterable<RuntimeModule>} iterable of modules (do not modify)
 */
getChunkRuntimeModulesIterable(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	return cgc.runtimeModules;
}

/**
 * 获取 chunk 中按执行顺序排序的 runtime 模块数组
 * @param {Chunk} chunk the chunk
 * @returns {RuntimeModule[]} array of modules in order of execution
 */
getChunkRuntimeModulesInOrder(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	const array = Array.from(cgc.runtimeModules); // 复制为数组
	array.sort(
		concatComparators(
			compareSelect(r => /** @type {RuntimeModule} */ (r).stage, compareIds), // 优先按 stage 排序
			compareModulesByIdentifier // 再按模块标识符排序
		)
	);
	return array;
}

/**
 * 获取 chunk 中参与 full hash 计算的模块(返回可迭代对象)
 * @param {Chunk} chunk the chunk
 * @returns {Iterable<RuntimeModule> | undefined} iterable of modules (do not modify)
 */
getChunkFullHashModulesIterable(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	return cgc.fullHashModules;
}

/**
 * 获取 chunk 中参与 full hash 计算的模块集合(只读集合)
 * @param {Chunk} chunk the chunk
 * @returns {ReadonlySet<RuntimeModule> | undefined} set of modules (do not modify)
 */
getChunkFullHashModulesSet(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	return cgc.fullHashModules;
}

/**
 * 获取 chunk 中参与 dependent hash 计算的模块(返回可迭代对象)
 * @param {Chunk} chunk the chunk
 * @returns {Iterable<RuntimeModule> | undefined} iterable of modules (do not modify)
 */
getChunkDependentHashModulesIterable(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	return cgc.dependentHashModules;
}

/**
 * 获取 chunk 中的 entry 模块及其对应的 chunkGroup 结构
 * @param {Chunk} chunk the chunk
 * @returns {Iterable<EntryModuleWithChunkGroup>} iterable of modules (do not modify)
 */
getChunkEntryModulesWithChunkGroupIterable(chunk) {
	const cgc = this._getChunkGraphChunk(chunk);
	return cgc.entryModules;
}

/**
 * 获取某个异步依赖块对应的 chunkGroup
 * @param {AsyncDependenciesBlock} depBlock the async block
 * @returns {ChunkGroup | undefined} the chunk group
 */
getBlockChunkGroup(depBlock) {
	return this._blockChunkGroups.get(depBlock);
}

/**
 * 将异步依赖块与 chunkGroup 建立连接关系
 * @param {AsyncDependenciesBlock} depBlock the async block
 * @param {ChunkGroup} chunkGroup the chunk group
 * @returns {void}
 */
connectBlockAndChunkGroup(depBlock, chunkGroup) {
	this._blockChunkGroups.set(depBlock, chunkGroup); // 记录映射关系
	chunkGroup.addBlock(depBlock); // 添加该 block 到 chunkGroup
}
相关推荐
小Tomkk5 分钟前
⭐️ StarRocks Web 使用介绍与实战指南
前端·ffmpeg
不一样的少年_9 分钟前
产品催: 1 天优化 Vue 官网 SEO?我用这个插件半天搞定(不重构 Nuxt)
前端·javascript·vue.js
-dcr10 分钟前
50.智能体
前端·javascript·人工智能·ai·easyui
行者9620 分钟前
Flutter跨平台开发适配OpenHarmony:进度条组件的深度实践
开发语言·前端·flutter·harmonyos·鸿蒙
云和数据.ChenGuang21 分钟前
Uvicorn 是 **Python 生态中用于运行异步 Web 应用的 ASGI 服务器**
服务器·前端·人工智能·python·机器学习
IT_陈寒23 分钟前
SpringBoot 3.0实战:这5个新特性让你的开发效率提升50%
前端·人工智能·后端
遗憾随她而去.31 分钟前
Webpack 面试题
前端·webpack·node.js
我要敲一万行32 分钟前
前端文件上传
前端·javascript
恋猫de小郭34 分钟前
Tailwind 因为 AI 的裁员“闹剧”结束,而 AI 对开源项目的影响才刚刚开始
前端·flutter·ai编程
要加油哦~34 分钟前
算法 | 整理数据结构 | 算法题中,JS 容器的选择
前端·javascript·算法