webpack 模块图 第 四 节

📦 模块导出相关

  • 判断模块是否提供某个导出(isExportProvided)
  • 获取模块整体的导出信息(getExportsInfo)
  • 获取具体某个导出的信息(getExportInfo)
  • 获取某个导出的只读信息(getReadOnlyExportInfo)
  • 获取模块在某运行时下被使用的导出(getUsedExports)

🧭 模块遍历索引相关

  • 获取/设置先序索引(getPreOrderIndex、setPreOrderIndex)
  • 如果未设置则设置先序索引(setPreOrderIndexIfUnset)
  • 获取/设置后序索引(getPostOrderIndex、setPostOrderIndex)
  • 如果未设置则设置后序索引(setPostOrderIndexIfUnset)

🌲 模块图深度相关

  • 获取模块深度(getDepth)
  • 设置模块深度(setDepth)
  • 如果当前深度更大则更新为较小的值(setDepthIfLower)

⏱ 模块异步状态

  • 判断模块是否为异步(isAsync)
  • 设置模块为异步(setAsync)

🧠 元信息存储

  • 获取或创建任意对象的元信息(getMeta)
  • 获取已存在的元信息(getMetaIfExisting)

🧊 缓存机制

  • 启用缓存(冻结模块图)(freeze)
  • 禁用缓存(解冻模块图)(unfreeze)
  • 带缓存的计算函数调用(cached)

🧩 模块级内存缓存

  • 设置模块级的内存缓存映射(setModuleMemCaches)
js 复制代码
/**
 * 判断模块是否提供了某个导出
 * @param {Module} module 模块对象
 * @param {string | string[]} exportName 导出的名称
 * @returns {boolean | null} 
 *   true 表示模块确实提供该导出,
 *   false 表示未提供,
 *   null 表示未知(无法判断)
 */
isExportProvided(module, exportName) {
	const mgm = this._getModuleGraphModule(module);
	const result = mgm.exports.isExportProvided(exportName);
	return result === undefined ? null : result;
}

/**
 * 获取模块的导出信息
 * @param {Module} module 模块对象
 * @returns {ExportsInfo} 模块的导出信息
 */
getExportsInfo(module) {
	const mgm = this._getModuleGraphModule(module);
	return mgm.exports;
}

/**
 * 获取模块中某个导出的信息
 * @param {Module} module 模块对象
 * @param {string} exportName 导出的名称
 * @returns {ExportInfo} 导出的详细信息
 */
getExportInfo(module, exportName) {
	const mgm = this._getModuleGraphModule(module);
	return mgm.exports.getExportInfo(exportName);
}

/**
 * 获取模块中某个导出的只读信息(不可修改)
 * @param {Module} module 模块对象
 * @param {string} exportName 导出的名称
 * @returns {ExportInfo} 导出的只读信息
 */
getReadOnlyExportInfo(module, exportName) {
	const mgm = this._getModuleGraphModule(module);
	return mgm.exports.getReadOnlyExportInfo(exportName);
}

/**
 * 获取模块在某个运行时下被使用的导出
 * @param {Module} module 模块对象
 * @param {RuntimeSpec} runtime 运行时
 * @returns {false | true | SortableSet<string> | null} 使用的导出:
 *   - false:模块完全未被使用;
 *   - true:只使用了模块对象(如 import * as ...);
 *   - SortableSet<string>:使用了指定的导出;
 *   - 空集合:模块被使用,但没有使用任何导出;
 *   - null:未知(最坏情况)
 */
getUsedExports(module, runtime) {
	const mgm = this._getModuleGraphModule(module);
	return mgm.exports.getUsedExports(runtime);
}

/**
 * 获取模块的先序遍历索引(用于模块排序)
 * @param {Module} module 模块对象
 * @returns {number | null} 索引或 null
 */
getPreOrderIndex(module) {
	const mgm = this._getModuleGraphModule(module);
	return mgm.preOrderIndex;
}

/**
 * 获取模块的后序遍历索引(用于模块排序)
 * @param {Module} module 模块对象
 * @returns {number | null} 索引或 null
 */
getPostOrderIndex(module) {
	const mgm = this._getModuleGraphModule(module);
	return mgm.postOrderIndex;
}

/**
 * 设置模块的先序遍历索引
 * @param {Module} module 模块对象
 * @param {number} index 索引值
 */
setPreOrderIndex(module, index) {
	const mgm = this._getModuleGraphModule(module);
	mgm.preOrderIndex = index;
}

/**
 * 如果未设置先序索引,则设置该索引
 * @param {Module} module 模块对象
 * @param {number} index 索引值
 * @returns {boolean} 是否成功设置
 */
setPreOrderIndexIfUnset(module, index) {
	const mgm = this._getModuleGraphModule(module);
	if (mgm.preOrderIndex === null) {
		mgm.preOrderIndex = index;
		return true;
	}
	return false;
}

/**
 * 设置模块的后序遍历索引
 * @param {Module} module 模块对象
 * @param {number} index 索引值
 */
setPostOrderIndex(module, index) {
	const mgm = this._getModuleGraphModule(module);
	mgm.postOrderIndex = index;
}

/**
 * 如果未设置后序索引,则设置该索引
 * @param {Module} module 模块对象
 * @param {number} index 索引值
 * @returns {boolean} 是否成功设置
 */
setPostOrderIndexIfUnset(module, index) {
	const mgm = this._getModuleGraphModule(module);
	if (mgm.postOrderIndex === null) {
		mgm.postOrderIndex = index;
		return true;
	}
	return false;
}

/**
 * 获取模块的深度(在模块图中的深度)
 * @param {Module} module 模块对象
 * @returns {number | null} 深度或 null
 */
getDepth(module) {
	const mgm = this._getModuleGraphModule(module);
	return mgm.depth;
}

/**
 * 设置模块的深度
 * @param {Module} module 模块对象
 * @param {number} depth 深度值
 */
setDepth(module, depth) {
	const mgm = this._getModuleGraphModule(module);
	mgm.depth = depth;
}

/**
 * 如果模块当前深度更大,则更新为更小的深度
 * @param {Module} module 模块对象
 * @param {number} depth 深度值
 * @returns {boolean} 是否成功设置
 */
setDepthIfLower(module, depth) {
	const mgm = this._getModuleGraphModule(module);
	if (mgm.depth === null || mgm.depth > depth) {
		mgm.depth = depth;
		return true;
	}
	return false;
}

/**
 * 判断模块是否是异步的
 * @param {Module} module 模块对象
 * @returns {boolean} 是否为异步模块
 */
isAsync(module) {
	const mgm = this._getModuleGraphModule(module);
	return mgm.async;
}

/**
 * 标记模块为异步
 * @param {Module} module 模块对象
 */
setAsync(module) {
	const mgm = this._getModuleGraphModule(module);
	mgm.async = true;
}

/**
 * 获取任意对象的元信息(如果不存在则创建一个)
 * @param {any} thing 任意对象
 * @returns {object} 元数据对象
 */
getMeta(thing) {
	let meta = this._metaMap.get(thing);
	if (meta === undefined) {
		meta = Object.create(null);
		this._metaMap.set(thing, /** @type {object} */ (meta));
	}
	return /** @type {object} */ (meta);
}

/**
 * 获取任意对象的元信息(如果不存在返回 undefined)
 * @param {any} thing 任意对象
 * @returns {object | undefined} 元数据对象
 */
getMetaIfExisting(thing) {
	return this._metaMap.get(thing);
}

/**
 * 冻结缓存(启用缓存机制)
 * @param {string=} cacheStage 缓存阶段名称
 */
freeze(cacheStage) {
	this._cache = new WeakTupleMap();
	this._cacheStage = cacheStage;
}

/**
 * 解冻缓存(禁用缓存机制)
 */
unfreeze() {
	this._cache = undefined;
	this._cacheStage = undefined;
}

/**
 * 使用缓存机制执行计算函数,返回缓存值或计算值
 * @template {any[]} T
 * @template V
 * @param {(moduleGraph: ModuleGraph, ...args: T) => V} fn 计算函数
 * @param {T} args 参数
 * @returns {V} 计算结果或缓存结果
 */
cached(fn, ...args) {
	if (this._cache === undefined) return fn(this, ...args);
	return this._cache.provide(fn, ...args, () => fn(this, ...args));
}

/**
 * 设置模块级别的内存缓存映射
 * @param {Map<Module, WeakTupleMap<any, any>>} moduleMemCaches 模块缓存映射表
 */
setModuleMemCaches(moduleMemCaches) {
	this._moduleMemCaches = moduleMemCaches;
}
相关推荐
wespaul4 小时前
VeapAI 自然语言操作实战|第 06 篇:AiConsole 前端运行时——一个 Hub,八个注册表
前端·人工智能·milvus
龙亘川4 小时前
健康服务规范化背后,数字化如何 “辅助赋能“
大数据·前端·人工智能·智慧城市·数据可视化
data analyse 4564 小时前
SourceMap 上传版本与报错版本对不上?版本校验与错误还原设计
大数据·前端·人工智能·数据分析
前端双越老师4 小时前
程序员 1v1 访谈系列第三期:先不要想在工作中有突破
前端·ai编程·全栈
小羊没烦恼!4 小时前
浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色
前端·数据库·后端·python·web安全·oracle
myaifas4 小时前
新人的第一个任务该怎么选
前端·产品经理
怕浪猫5 小时前
前端转全栈最低成本的技术栈选择
前端·javascript·面试
狂师5 小时前
AI时代我们要如何玩抓包测试:Reqable + AI Agent
前端·程序员·测试
data analyse 4565 小时前
页面卸载时埋点上报总丢失?sendBeacon 上报与补偿方案
大数据·运维·服务器·前端·数据库·人工智能·数据分析
WebInfra5 小时前
Rsdoctor 2.0 发布:Agent 驱动的全自动优化工具
前端·javascript·node.js