webpack 模块图 第 五 节


  • 依赖缓存机制

    • dependencyCacheProvide(dependency, ...args)

      • 提供依赖级的缓存计算功能,优先使用模块级缓存,其次使用全局缓存。
  • 兼容旧版 API 的方法(Webpack 6 中将被移除)

    • static getModuleGraphForModule(module, deprecateMessage, deprecationCode)

      • 获取指定模块对应的 ModuleGraph,带有弃用提示。
    • static setModuleGraphForModule(module, moduleGraph)

      • 设置模块与 ModuleGraph 的关联,用于兼容旧逻辑。
    • static clearModuleGraphForModule(module)

      • 清除模块与 ModuleGraph 的映射。
  • 内部数据结构

    • moduleGraphForModuleMap

      • WeakMap<Module, ModuleGraph>:用于旧 API 维护模块和模块图的映射关系。
    • deprecateMap

      • Map<string, (module) => ModuleGraph>:缓存已创建的弃用函数,避免重复生成。
  • 导出

    • 导出 ModuleGraph 类。
    • 同时导出 ModuleGraphConnection(用于表示模块间连接关系,代码中未展示)。
js 复制代码
class ModuleGraph {

	/**
	 * 为指定的依赖提供缓存机制。
	 * 如果已经有缓存的结果就直接返回,
	 * 否则执行传入的计算函数并缓存其返回值。
	 *
	 * @param {Dependency} dependency 依赖对象
	 * @param {...any} args 额外参数,最后一个是函数:fn(moduleGraph, dependency, ...args)
	 * @returns {any} 计算值或缓存值
	 */
	dependencyCacheProvide(dependency, ...args) {
		const fn = args.pop(); // 取出最后一个参数(实际用于计算的函数)
		if (this._moduleMemCaches && this._cacheStage) {
			// 从模块级内存缓存中尝试获取
			const memCache = this._moduleMemCaches.get(
				/** @type {Module} */ (this.getParentModule(dependency))
			);
			if (memCache !== undefined) {
				return memCache.provide(dependency, this._cacheStage, ...args, () =>
					fn(this, dependency, ...args)
				);
			}
		}
		// 若未启用缓存机制,则直接调用函数
		if (this._cache === undefined) return fn(this, dependency, ...args);
		// 否则使用通用缓存机制
		return this._cache.provide(dependency, ...args, () =>
			fn(this, dependency, ...args)
		);
	}

	// 以下三个方法为旧 API 的兼容支持,Webpack 6 将会移除

	/**
	 * (⚠️兼容方法)获取某个模块关联的 ModuleGraph 实例。
	 * 若首次调用则创建弃用警告函数并存入 Map。
	 *
	 * @param {Module} module 模块对象
	 * @param {string} deprecateMessage 弃用提示信息
	 * @param {string} deprecationCode 弃用代码标识
	 * @returns {ModuleGraph} 对应的模块图实例
	 */
	static getModuleGraphForModule(module, deprecateMessage, deprecationCode) {
		const fn = deprecateMap.get(deprecateMessage);
		if (fn) return fn(module);
		const newFn = util.deprecate(
			module => {
				const moduleGraph = moduleGraphForModuleMap.get(module);
				if (!moduleGraph)
					throw new Error(
						`${deprecateMessage}There was no ModuleGraph assigned to the Module for backward-compat (Use the new API)`
					);
				return moduleGraph;
			},
			`${deprecateMessage}: Use new ModuleGraph API`,
			deprecationCode
		);
		deprecateMap.set(deprecateMessage, newFn);
		return newFn(module);
	}

	/**
	 * (⚠️兼容方法)为模块设置 ModuleGraph 映射。
	 *
	 * @param {Module} module 模块对象
	 * @param {ModuleGraph} moduleGraph 模块图对象
	 */
	static setModuleGraphForModule(module, moduleGraph) {
		moduleGraphForModuleMap.set(module, moduleGraph);
	}

	/**
	 * (⚠️兼容方法)清除模块与 ModuleGraph 的映射。
	 *
	 * @param {Module} module 模块对象
	 */
	static clearModuleGraphForModule(module) {
		moduleGraphForModuleMap.delete(module);
	}
}

// 以下为旧 API 支持数据结构(Webpack 6 将移除)

/** 模块到 ModuleGraph 的映射表(用于旧 API) */
const moduleGraphForModuleMap = new WeakMap();

/** 弃用警告函数映射表(deprecateMessage -> fn) */
const deprecateMap = new Map();

module.exports = ModuleGraph;
module.exports.ModuleGraphConnection = ModuleGraphConnection;
相关推荐
阿祖zu几秒前
别再优化 RAG 了,适配 Agent 的 LLM Wiki 知识库理念
前端·后端·aigc
kyriewen22 分钟前
前端错误监控最全指南:捕获 JS 异常、Promise 拒绝、资源加载失败,附上报代码
前端·javascript·监控
狗哥哥34 分钟前
船队运营可视化技术方案
前端
大家的林语冰37 分钟前
ESLint 近期动态大全,新版本正式发布,antfu 大佬推荐的插件也更新了!
前端·javascript·前端工程化
只会cv的前端攻城狮38 分钟前
DSL 领域模型架构设计:消灭 CRUD 重复工作
前端·架构
码事漫谈1 小时前
时序数据库2026盘点:国产数据库如何以“融合多模”走出差异化之路?
前端·后端
道友可好2 小时前
让 AI 自己验收,等于让学生自己批卷
前端·人工智能·后端
yingyima2 小时前
Go 语言正则表达式速查手册:30 分钟掌握核心语法与实战技巧
前端
大蝴蝶博努奇a2 小时前
使用ChatGPT 解决各类代码报错
前端
胡志辉2 小时前
深入浅出 call、apply、bind
前端·javascript·后端