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;
相关推荐
Amy_cx12 分钟前
在表单输入框按回车页面刷新的问题
前端·elementui
dancing99926 分钟前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序
后海 0_o1 小时前
2025前端微服务 - 无界 的实战应用
前端·微服务·架构
Scabbards_1 小时前
CPT304-2425-S2-Software Engineering II
前端
小满zs1 小时前
Zustand 第二章(状态处理)
前端·react.js
程序猿小D1 小时前
第16节 Node.js 文件系统
linux·服务器·前端·node.js·编辑器·vim
萌萌哒草头将军1 小时前
🚀🚀🚀Prisma 发布无 Rust 引擎预览版,安装和使用更轻量;支持任何 ORM 连接引擎;支持自动备份...
前端·javascript·vue.js
狼性书生1 小时前
uniapp实现的简约美观的星级评分组件
前端·uni-app·vue·组件
书语时1 小时前
ES6 Promise 状态机
前端·javascript·es6
拉不动的猪2 小时前
管理不同权限用户的左侧菜单展示以及权限按钮的启用 / 禁用之其中一种解决方案
前端·javascript·面试