Compilation
模块由 Compiler
用于创建新的编译(或构建)。compilation
实例可以访问所有模块及其依赖项(其中大部分是循环引用)。它是应用程序依赖图中所有模块的字面编译。在编译阶段,模块被加载、封装、优化、分块、哈希和恢复。
Compilation
类也扩展了 Tapable
并提供了以下生命周期钩子。它们可以像编译器钩子一样被监听。
compilation.hooks.someHook.tap(/* ... */);
与编译器一样,tapAsync
和 tapPromise
也可能可用,具体取决于钩子的类型。
SyncHook
在模块构建开始之前触发,可用于修改模块。
module
compilation.hooks.buildModule.tap(
'SourceMapDevToolModuleOptionsPlugin',
(module) => {
module.useSourceMap = true;
}
);
SyncHook
在重建模块之前触发。
module
SyncHook
模块构建失败时运行。
module
error
SyncHook
模块成功构建后执行。
module
AsyncSeriesHook
所有模块无错误构建完成后调用。
modules
SyncHook
模块重建完成后执行,无论成功还是有错误。
module
SyncHook
当编译停止接受新模块时触发。
SyncHook
当编译开始接受新模块时触发。
SyncBailHook
在依赖优化开始时触发。
modules
SyncHook
在依赖优化之后触发。
modules
SyncHook
afterChunks
钩子在分块和模块图创建之后、优化之前调用。此钩子提供了在必要时检查、分析和修改分块图的机会。
这里是关于如何使用 compilation.hooks.afterChunks
钩子的一个示例。
chunks
SyncHook
在优化阶段开始时触发。
SyncBailHook
在模块优化阶段开始时调用。插件可以监听此钩子以对模块执行优化。
modules
SyncHook
模块优化完成后调用。
modules
SyncBailHook
在分块优化阶段开始时调用。插件可以监听此钩子以对分块执行优化。
chunks
SyncHook
分块优化完成后触发。
chunks
AsyncSeriesHook
在优化依赖树之前调用。插件可以监听此钩子以执行依赖树优化。
chunks
modules
SyncHook
依赖树优化成功完成后调用。
chunks
modules
SyncBailHook
在树优化之后,分块模块优化开始时调用。插件可以监听此钩子以执行分块模块的优化。
chunks
modules
SyncHook
分块模块优化成功完成后调用。
chunks
modules
SyncBailHook
调用此钩子以确定是否存储记录。返回任何 !== false
的值将阻止其他所有“记录”钩子(record
、recordModules
、recordChunks
和 recordHash
)的执行。
SyncHook
从记录中恢复模块信息。
modules
records
SyncHook
在为每个模块分配 id
之前执行。
modules
SyncHook
调用此钩子为每个模块分配 id
。
modules
SyncHook
在模块 id
优化开始时调用。
modules
SyncHook
模块 id
优化阶段完成后调用。
modules
SyncHook
从记录中恢复分块信息。
chunks
records
SyncHook
在为每个分块分配 id
之前执行。
chunks
SyncHook
调用此钩子为每个分块分配 id
。
chunks
SyncHook
在分块 id
优化阶段开始时调用。
chunks
SyncHook
分块 id
优化完成后触发。
chunks
SyncHook
将模块信息存储到记录中。如果 shouldRecord
返回一个真值,则会触发此钩子。
modules
records
SyncHook
将分块信息存储到记录中。仅当 shouldRecord
返回一个真值时才会触发此钩子。
chunks
records
SyncHook
在模块哈希之前调用。
syncHook
在模块哈希之后调用。
SyncHook
在编译哈希之前调用。
SyncHook
在编译哈希之后调用。
SyncHook
将记录哈希信息存储到 records
中。仅当 shouldRecord
返回一个真值时才会触发此钩子。
records
SyncHook
将 compilation
的信息存储到 records
中。仅当 shouldRecord
返回一个真值时才会触发此钩子。
compilation
records
SyncHook
在模块资产创建之前执行。
SyncHook
为分块创建额外的资产。
chunks
SyncBailHook
调用此钩子以确定是否生成分块资产。返回任何 !== false
的值将允许生成分块资产。
SyncHook
在创建分块资产之前执行。
AsyncSeriesHook
为编译创建额外的资产。例如,此钩子可用于下载图片。
compilation.hooks.additionalAssets.tapAsync('MyPlugin', (callback) => {
download('https://img.shields.io/npm/v/webpack.svg', function (resp) {
if (resp.status === 200) {
compilation.assets['webpack-version.svg'] = toAsset(resp);
callback();
} else {
callback(
new Error('[webpack-example-plugin] Unable to download the image')
);
}
});
});
AsyncSeriesHook
优化任何分块资产。资产存储在 compilation.assets
中。一个 Chunk
有一个 files
属性,指向由分块创建的所有文件。任何额外的分块资产都存储在 compilation.additionalChunkAssets
中。
chunks
这里是一个为每个分块添加横幅的示例。
compilation.hooks.optimizeChunkAssets.tapAsync(
'MyPlugin',
(chunks, callback) => {
chunks.forEach((chunk) => {
chunk.files.forEach((file) => {
compilation.assets[file] = new ConcatSource(
'/**Sweet Banner**/',
'\n',
compilation.assets[file]
);
});
});
callback();
}
);
SyncHook
分块资产已优化。
chunks
这里是来自 @boopathi 的一个插件示例,它精确地输出了每个分块中的内容。
compilation.hooks.afterOptimizeChunkAssets.tap('MyPlugin', (chunks) => {
chunks.forEach((chunk) => {
console.log({
id: chunk.id,
name: chunk.name,
includes: chunk.getModules().map((module) => module.request),
});
});
});
AsyncSeriesHook
优化存储在 compilation.assets
中的所有资产。
assets
SyncHook
资产已优化。
assets
AsyncSeriesHook
资产处理。
钩子参数
name: string
— 插件的名称stage: Stage
— 要监听的阶段(参见下方支持的阶段列表)additionalAssets?: true | (assets, [callback]) => (void | Promise<void>)
— 用于额外资产的回调(见下方)回调参数
assets: { [pathname: string]: Source }
— 一个普通对象,其中键是资产的路径名,值是由 Source
表示的资产数据。示例
compilation.hooks.processAssets.tap(
{
name: 'MyPlugin',
stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS, // see below for more stages
},
(assets) => {
console.log('List of assets and their sizes:');
Object.entries(assets).forEach(([pathname, source]) => {
console.log(`— ${pathname}: ${source.size()} bytes`);
});
}
);
除了 name
和 stage
,你还可以传递一个 additionalAssets
5.8.0+ 选项,它接受 true
值或一个接收 assets
作为第一个参数的回调函数。
true
— 对插件后续添加的资产再次运行提供的回调。
在此模式下,回调将被多次调用:一次用于在指定阶段之前添加的资产,多次用于插件后续添加的资产(在此阶段或下一阶段)。
compilation.hooks.processAssets.tap(
{
name: 'MyPlugin',
stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
additionalAssets: true,
},
(assets) => {
// this function will be called multiple times with each bulk of assets
}
);
(assets, [callback]) => (void | Promise<void>)
— 对插件后续添加的资产(在此阶段或下一阶段)运行指定的回调。回调必须符合所使用的 tap 方法的类型(例如,与 tapPromise()
一起使用时,它应返回一个 Promise)。
compilation.hooks.processAssets.tap(
{
name: 'MyPlugin',
stage: Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING,
additionalAssets: (assets) => {
// this function potentially could be called multiple times for assets added on later stages
},
},
(assets) => {
// this function will be called once with assets added by plugins on prior stages
}
);
以下是支持的阶段列表(按处理顺序):
PROCESS_ASSETS_STAGE_ADDITIONAL
— 向编译中添加额外资产。PROCESS_ASSETS_STAGE_PRE_PROCESS
— 资产的基本预处理。PROCESS_ASSETS_STAGE_DERIVED
— 从现有资产派生新资产。PROCESS_ASSETS_STAGE_ADDITIONS
— 向现有资产添加额外部分,例如横幅或初始化代码。PROCESS_ASSETS_STAGE_OPTIMIZE
— 以通用方式优化现有资产。PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT
— 优化现有资产的数量,例如通过合并它们。PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY
— 优化现有资产的兼容性,例如添加 polyfills 或厂商前缀。PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE
— 优化现有资产的大小,例如通过最小化或省略空白。PROCESS_ASSETS_STAGE_DEV_TOOLING
— 向资产添加开发工具,例如通过提取源映射。PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE
5.8.0+ — 优化现有资产的数量,例如通过将资产内联到其他资产中。PROCESS_ASSETS_STAGE_SUMMARIZE
— 总结现有资产列表。PROCESS_ASSETS_STAGE_OPTIMIZE_HASH
— 优化资产的哈希,例如通过生成资产内容的真实哈希。PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER
— 优化现有资产的传输,例如通过将压缩(gzip)文件准备为单独的资产。PROCESS_ASSETS_STAGE_ANALYSE
— 分析现有资产。PROCESS_ASSETS_STAGE_REPORT
— 为报告目的创建资产。此钩子不会自动提供“资产信息”元数据。如果需要,你必须使用编译实例和提供的资产路径名手动解析此元数据。这将在 webpack 的未来版本中得到改进。
示例
compilation.hooks.processAssets.tap(
{
/** … */
},
(assets) => {
Object.entries(assets).forEach(([pathname, source]) => {
const assetInfo = compilation.assetsInfo.get(pathname);
// @todo: do something with "pathname", "source" and "assetInfo"
});
}
);
SyncHook
在 processAssets
钩子无错误完成后调用。
SyncBailHook
调用此钩子以确定编译是否需要解除封装以包含其他文件。
AsyncSeriesHook
在 needAdditionalSeal
之后立即执行。
SyncHook
触发以发出每个分块的哈希。
chunk
chunkHash
SyncHook
当模块中的资产添加到编译时调用。
module
filename
SyncHook
当分块中的资产添加到编译时触发。
chunk
filename
SyncWaterfallHook
调用此钩子以确定资产的路径。
path
options
SyncBailHook
调用此钩子以确定资产在发出后是否需要进一步处理。
SyncHook
设置子编译器后执行。
childCompiler
compilerName
compilerIndex
自 webpack v5 起,normalModuleLoader
钩子已被移除。现在要访问加载器,请改用 NormalModule.getCompilationHooks(compilation).loader
。
HookMap
此 HookMap 类似于当使用预设时触发的一系列操作。它接受一个选项对象。当插件管理预设时,它应该小心地修改此对象中的设置,而不要替换现有设置。
options
context
这里是一个说明性的插件示例
compilation.hooks.statsPreset.for('my-preset').tap('MyPlugin', (options) => {
if (options.all === undefined) options.all = true;
});
此插件确保对于预设 'my-preset'
,如果 all
选项未定义,则默认为 true。
SyncHook
此钩子用于将选项对象转换为一致的格式,以便后续钩子轻松使用。它还确保缺失的选项被设置为其默认值。
options
context
这里是一个说明性的插件示例
compilation.hooks.statsNormalize.tap('MyPlugin', (options) => {
if (options.myOption === undefined) options.myOption = [];
if (!Array.isArray(options.myOption)) options.myOptions = [options.myOptions];
});
在此插件中,如果 myOption
缺失,它会将其设置为空数组。此外,它确保 myOption
始终是一个数组,即使它最初被定义为单个值。
此钩子提供对 StatsFactory class
的访问,用于特定选项。
statsFactory
options
HookMap
object
data
context
data
包含类。object
是一个应添加属性的对象。context
提供上下文信息,例如路径上的类。
示例
compilation.hooks.statsFactory.tap('MyPlugin', (statsFactory, options) => {
statsFactory.hooks.extract
.for('compilation')
.tap('MyPlugin', (object, compilation) => {
object.customProperty = MyPlugin.getCustomValue(compilation);
});
});
HookMap
在每个级别上用结果调用。
result
context
此钩子提供对 StatsPrinter class
的访问,用于特定选项。
statsPrinter
options
HookMap
当某个部分需要打印时,会调用此钩子。
object
context
HookMap
此钩子在某个部分的最终字符串生成时调用。
result
context