webpack 模块图 第 四 节

📦 模块导出相关

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

🧭 模块遍历索引相关

  • 获取/设置先序索引(getPreOrderIndexsetPreOrderIndex
  • 如果未设置则设置先序索引(setPreOrderIndexIfUnset
  • 获取/设置后序索引(getPostOrderIndexsetPostOrderIndex
  • 如果未设置则设置后序索引(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;
}
相关推荐
肥肥呀呀呀28 分钟前
在Flutter上如何实现按钮的拖拽效果
前端·javascript·flutter
Zero10171344 分钟前
【React的useMemo钩子详解】
前端·react.js·前端框架
养军博客1 小时前
spring boot3.0自定义校验注解:文章状态校验示例
java·前端·spring boot
uperficialyu1 小时前
2025年01月10日浙江鑫越系统科技前端面试
前端·科技·面试
付朝鲜1 小时前
用自写的jQuery库+Ajax实现了省市联动
java·前端·javascript·ajax·jquery
coderYYY1 小时前
多个el-form-item两列布局排齐且el-select/el-input组件宽度撑满
前端·javascript·vue.js·elementui·前端框架
荔枝吖2 小时前
项目中会出现的css样式
前端·css·html
Dontla2 小时前
何时需要import css文件?怎么知道需要导入哪些css文件?为什么webpack不提示CSS导入?(导入css导入规则、css导入规范)
前端·css·webpack
小堃学编程2 小时前
前端学习(2)—— CSS详解与使用
前端·css·学习
蓝婷儿2 小时前
第一章:HTML基石·现实的骨架
前端·html