js
复制代码
/**
* 生成模块信息注释字符串
*/
comment({ request, chunkName, chunkReason, message, exportName }) {
let content;
if (this.outputOptions.pathinfo) {
// 如果配置开启 pathinfo,包含更多字段:message、request、chunkName、chunkReason
content = [message, request, chunkName, chunkReason]
.filter(Boolean) // 过滤掉 undefined/null/空串
.map(item => this.requestShortener.shorten(item)) // 使用 requestShortener 缩短
.join(" | "); // 用 | 分隔
} else {
// 未开启 pathinfo,只包含部分字段
content = [message, chunkName, chunkReason]
.filter(Boolean)
.map(item => this.requestShortener.shorten(item))
.join(" | ");
}
if (!content) return ""; // 如果没生成内容则返回空字符串
if (this.outputOptions.pathinfo) {
// pathinfo 开启时使用多行注释风格
return `${Template.toComment(content)} `;
}
// 否则使用单行注释
return `${Template.toNormalComment(content)} `;
}
/**
* 生成缺失模块的错误语句代码块(用于同步语句)
*/
throwMissingModuleErrorBlock({ request }) {
const err = `Cannot find module '${request}'`; // 构建错误信息文本
return `var e = new Error(${JSON.stringify(err)}); e.code = 'MODULE_NOT_FOUND'; throw e;`; // 返回 JS 错误抛出代码
}
/**
* 生成一个函数体用于抛出缺失模块错误(用于异步调用中)
*/
throwMissingModuleErrorFunction({ request }) {
return `function webpackMissingModule() { ${this.throwMissingModuleErrorBlock({ request })} }`; // 返回一个函数定义字符串
}
/**
* 使用 IIFE(立即执行函数表达式)封装错误抛出(用于表达式场景)
*/
missingModule({ request }) {
return `Object(${this.throwMissingModuleErrorFunction({ request })}())`; // 执行错误函数返回结果作为对象表达式
}
/**
* 返回缺失模块抛错语句,带分号和换行(用于生成语句块)
*/
missingModuleStatement({ request }) {
return `${this.missingModule({ request })};\n`;
}
/**
* 返回一个 Promise 封装的缺失模块错误(用于动态 import 场景)
*/
missingModulePromise({ request }) {
return `Promise.resolve().then(${this.throwMissingModuleErrorFunction({ request })})`; // 异步抛错函数作为 then 回调
}
/**
* 生成针对"弱依赖"模块缺失的错误抛出代码(支持三种形式)
*/
weakError({ module, chunkGraph, request, idExpr, type }) {
const moduleId = chunkGraph.getModuleId(module); // 获取模块 ID
const errorMessage =
moduleId === null
? JSON.stringify("Module is not available (weak dependency)") // ID 为空,使用默认错误提示
: idExpr
? `"Module '" + ${idExpr} + "' is not available (weak dependency)"` // 自定义表达式形式
: JSON.stringify(`Module '${moduleId}' is not available (weak dependency)`); // 正常 ID 错误信息
const comment = request ? `${Template.toNormalComment(request)} ` : ""; // 加上注释
const errorStatements = `var e = new Error(${errorMessage}); ${comment}e.code = 'MODULE_NOT_FOUND'; throw e;`; // 构造错误抛出代码块
switch (type) {
case "statements":
return errorStatements; // 返回纯语句形式
case "promise":
return `Promise.resolve().then(${this.basicFunction("", errorStatements)})`; // 封装为 Promise 形式
case "expression":
return this.iife("", errorStatements); // 封装为 IIFE 表达式形式
}
}
/**
* 生成模块 ID 的字符串表达式
*/
moduleId({ module, chunkGraph, request, weak }) {
if (!module) {
return this.missingModule({ request }); // 模块不存在,返回缺失模块表达式
}
const moduleId = chunkGraph.getModuleId(module); // 获取模块 ID
if (moduleId === null) {
if (weak) {
return "null /* weak dependency, without id */"; // 弱依赖无 ID 返回 null
}
// 非弱依赖却没有 ID 抛出错误
throw new Error(`RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(module, chunkGraph)}`);
}
// 返回模块 ID + 注释
return `${this.comment({ request })}${JSON.stringify(moduleId)}`;
}
/**
* 返回 require(moduleId) 的表达式(并处理弱依赖缺失情况)
*/
moduleRaw({ module, chunkGraph, request, weak, runtimeRequirements }) {
if (!module) {
return this.missingModule({ request }); // 模块不存在返回错误
}
const moduleId = chunkGraph.getModuleId(module);
if (moduleId === null) {
if (weak) {
// 弱依赖但无 ID,返回错误表达式形式
return this.weakError({ module, chunkGraph, request, type: "expression" });
}
// 非弱依赖却无 ID 抛出异常
throw new Error(`RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(module, chunkGraph)}`);
}
runtimeRequirements.add(RuntimeGlobals.require); // 添加运行时代码中 require 的依赖
return `${RuntimeGlobals.require}(${this.moduleId({ module, chunkGraph, request, weak })})`; // 返回 require(moduleId)
}
/**
* 返回模块导出表达式(实际就是调用 moduleRaw)
*/
moduleExports({ module, chunkGraph, request, weak, runtimeRequirements }) {
return this.moduleRaw({ module, chunkGraph, request, weak, runtimeRequirements });
}