-
模块导入部分:
InitFragment
:用于生成初始化代码片段。RuntimeGlobals
:包含 Webpack 运行时代码使用的全局变量集合。Template
:用于代码字符串生成和格式化。ArrayHelpers.equals
:数组比较工具函数。compileBooleanMatcher
:编译 runtime 条件判断函数。propertyAccess
:安全访问对象属性(如a.b.c
的路径形式)。forEachRuntime
、subtractRuntime
:操作 runtime 集合的工具函数。
-
类型定义部分(用于 TypeScript 注解或 JSDoc) :
- 涉及 Webpack 编译过程中的关键类型,如
Module
,Chunk
,Compilation
,ChunkGraph
,ModuleGraph
等。 - 这些 typedef 保证代码注释中对参数、返回值的结构清晰。
- 涉及 Webpack 编译过程中的关键类型,如
-
工具函数
noModuleIdErrorMessage
:-
用于调试时输出某个模块未分配 ID 的详细错误信息。
-
包含:
- 模块标识符。
- 所属 chunk(可能是空)。
- 所有指向该模块的依赖连接详情。
-
-
工具函数
getGlobalObject
:-
目的:返回一个"安全可用"的全局对象访问表达式。
-
逻辑:
- 若是合法标识符或函数调用表达式,直接返回。
- 否则使用
Object(...)
包裹,防止非法表达式导致运行时报错。
-
js
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// 声明使用 MIT 开源许可证,作者是 Tobias Koppers(Webpack 的作者)
"use strict";
// 使用严格模式,提高代码的健壮性,防止一些隐式错误
const InitFragment = require("./InitFragment");
// 引入 InitFragment 类,用于代码生成阶段插入初始化片段(如 `__webpack_require__` 注册等)
const RuntimeGlobals = require("./RuntimeGlobals");
// 引入 Webpack 的全局运行时代码标识集合,如 `__webpack_require__`, `__webpack_modules__` 等
const Template = require("./Template");
// 引入 Template 工具类,用于生成字符串模板或辅助代码格式化
const { equals } = require("./util/ArrayHelpers");
// 引入数组辅助函数中的 `equals` 方法,用于判断两个数组是否相等
const compileBooleanMatcher = require("./util/compileBooleanMatcher");
// 引入用于编译布尔匹配器的工具函数,该函数根据配置生成判断 runtime 条件的函数
const propertyAccess = require("./util/propertyAccess");
// 引入属性访问辅助函数,用于安全访问对象的嵌套属性,如 `a.b.c` 形式字符串转换
const { forEachRuntime, subtractRuntime } = require("./util/runtime");
// 引入 runtime 工具函数:
// `forEachRuntime` 用于遍历 runtime(支持多个 runtime)
// `subtractRuntime` 用于从一个 runtime 集合中移除另一个集合
/** @typedef {import("../declarations/WebpackOptions").Environment} Environment */
// 引入类型定义:Environment 表示 Webpack 中的环境配置选项
/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
// 引入类型定义:OutputOptions 表示 Webpack 中输出配置的结构(已标准化)
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
// 引入类型定义:表示异步依赖块结构,用于处理 `import()` 形成的 chunk
/** @typedef {import("./Chunk")} Chunk */
// 引入类型定义:Chunk 表示打包生成的一个代码块
/** @typedef {import("./ChunkGraph")} ChunkGraph */
// 引入类型定义:ChunkGraph 表示模块与 chunk 的关系图结构
/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
// 引入类型定义:CodeGenerationResults 表示整个编译过程中生成的代码结果合集
/** @typedef {import("./CodeGenerationResults").CodeGenerationResult} CodeGenerationResult */
// 引入类型定义:CodeGenerationResult 表示某个模块生成的代码信息
/** @typedef {import("./Compilation")} Compilation */
// 引入类型定义:Compilation 表示一次完整的编译过程上下文对象
/** @typedef {import("./Dependency")} Dependency */
// 引入类型定义:Dependency 表示模块依赖关系的抽象结构
/** @typedef {import("./Module")} Module */
// 引入类型定义:Module 表示 Webpack 中的模块抽象对象
/** @typedef {import("./Module").BuildMeta} BuildMeta */
// 引入类型定义:BuildMeta 表示模块构建的元数据,如是否是 `esm`、是否是异步等
/** @typedef {import("./Module").RuntimeRequirements} RuntimeRequirements */
// 引入类型定义:RuntimeRequirements 表示模块在运行时代码所需的全局依赖集合
/** @typedef {import("./ModuleGraph")} ModuleGraph */
// 引入类型定义:ModuleGraph 表示模块之间依赖关系的图结构
/** @typedef {import("./RequestShortener")} RequestShortener */
// 引入类型定义:RequestShortener 用于压缩模块路径,使日志更简洁可读
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
// 引入类型定义:RuntimeSpec 表示 runtime 的类型定义,可以是单个 runtime 或多个 runtime
/**
* @param {Module} module the module
* @param {ChunkGraph} chunkGraph the chunk graph
* @returns {string} error message
*/
// 定义一个辅助函数,用于生成模块没有被分配 ID 时的错误信息
const noModuleIdErrorMessage = (
module,
chunkGraph
) => `Module ${module.identifier()} has no id assigned.
This should not happen.
// 上面一句是主错误提示,指出模块未被分配 ID 是不应该发生的
It's in these chunks: ${
Array.from(
chunkGraph.getModuleChunksIterable(module),
c => c.name || c.id || c.debugId
).join(", ") || "none"
// 获取该模块所属的所有 chunk 名称或 ID,如果没有,则输出 "none"
} (If module is in no chunk this indicates a bug in some chunk/module optimization logic)
// 如果模块不在任何 chunk 中,可能说明 chunk/module 优化逻辑中存在 bug
Module has these incoming connections: ${Array.from(
chunkGraph.moduleGraph.getIncomingConnections(module),
connection =>
`\n - ${
connection.originModule && connection.originModule.identifier()
// 获取每个连接的源模块 ID
} ${connection.dependency && connection.dependency.type} ${
// 获取该连接对应的依赖类型
(connection.explanations &&
Array.from(connection.explanations).join(", ")) ||
// 如果有解释信息,拼接为字符串
""
}`
// 拼接每条连接的字符串信息
).join("")}`;
// 输出所有指向该模块的依赖关系列表
/**
* @param {string | undefined} definition global object definition
* @returns {string | undefined} save to use global object
*/
// 定义一个函数:用于安全地格式化全局对象定义(如 globalThis, window, self)
function getGlobalObject(definition) {
if (!definition) return definition;
// 如果没有定义,直接返回 undefined
const trimmed = definition.trim();
// 去除前后空格
if (
// identifier, we do not need real identifier regarding ECMAScript/Unicode
/^[_\p{L}][_0-9\p{L}]*$/iu.test(trimmed) ||
// 如果是合法的变量名(即 ECMAScript 标识符)
// iife
// call expression
// expression in parentheses
/^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu.test(trimmed)
)
// 或者是立即执行函数表达式 / 调用表达式,也认为是安全的
return trimmed;
// 安全直接返回
return `Object(${trimmed})`;
// 否则,用 `Object(...)` 包裹,使其在运行时代码中安全执行
}