Compilation 模块会被 Compiler 用来创建新的 compilation 对象(或新的 build 对象)。
compilation 实例能够访问所有的模块和它们的依赖(大部分是循环依赖)。
它会对应用程序的依赖图中所有模块,
进行字面上的编译(literal compilation)。
在编译阶段,模块会被加载(load)、封存(seal)、优化(optimize)、
分块(chunk)、哈希(hash)和重新创建(restore)。
Compilation 类扩展(extend)自 Tapable,并提供了以下生命周期钩子。
可以按照 compiler 钩子的相同方式来调用 tap:
compilation.hooks.someHook.tap(/* ... */);和 compiler 用法相同,取决于不同的钩子类型,
所以也可以在某些钩子上访问 tapAsync 和 tapPromise。
SyncHook
在模块构建开始之前触发,可以用来修改模块。
modulecompilation.hooks.buildModule.tap(
'SourceMapDevToolModuleOptionsPlugin',
(module) => {
module.useSourceMap = true;
}
);SyncHook
在重新构建一个模块之前触发。
moduleSyncHook
模块构建失败时执行。
module errorSyncHook
模块构建成功时执行。
moduleAsyncSeriesHook
所有模块都完成构建并且没有错误时执行。
modulesSyncHook
一个模块完成重新构建时执行,在都成功或有错误的情况下。
moduleSyncHook
compilation 对象停止接收新的模块时触发。
SyncHook
compilation 对象开始接收新模块时触发。
SyncBailHook
依赖优化开始时触发。
modulesSyncHook
依赖优化之后触发。
modulesSyncHook
优化阶段开始时触发。
SyncBailHook
在模块优化阶段开始时调用。插件可以 tap 此钩子对模块进行优化。
modulesSyncHook
在模块优化完成之后调用。
modulesSyncBailHook
在 chunk 优化阶段开始时调用。插件可以 tap 此钩子对 chunk 执行优化。
chunksSyncHook
chunk 优化完成之后触发。
chunksAsyncSeriesHook
在优化依赖树之前调用。插件可以 tap 此钩子执行依赖树优化。
chunks modulesSyncHook
在依赖树优化成功完成之后调用。
chunks modulesSyncBailHook
在树优化之后,chunk 模块优化开始时调用。插件可以 tap 此钩子来执行 chunk 模块的优化。
chunks modulesSyncHook
在 chunk 模块优化成功完成之后调用。
chunks modulesSyncBailHook
调用来决定是否存储 record。返回任何内容 !== false 将阻止执行所有其他 "record" 钩子(record, recordModules, recordChunks 和 recordHash)。
SyncHook
从 record 中恢复模块信息。
modules recordsSyncHook
在为每个模块分配 id 之前执行。
modulesSyncHook
调用来每个模块分配一个 id。
modulesSyncHook
在模块 id 优化开始时调用。
modulesSyncHook
在模块 id 优化完成时调用。
modulesSyncHook
从 record 中恢复 chunk 信息。
chunks recordsSyncHook
在为每个 chunk 分配 id 之前执行。
chunksSyncHook
调用时,会为每个 chunk 分配一个 id。
chunksSyncHook
在 chunk id 优化阶段开始时调用。
chunksSyncHook
chunk id 优化结束之后触发。
chunksSyncHook
将模块信息存储到 record 中。shouldRecord 返回 truthy 值时触发。
modules recordsSyncHook
将 chunk 存储到 record 中。shouldRecord 返回 truthy 值时触发。
chunks recordsSyncHook
在创建模块哈希(hash)之前。
syncHook
在创建模块哈希(hash)之后。
SyncHook
在 compilation 添加哈希(hash)之前。
SyncHook
在 compilation 添加哈希(hash)之后。
SyncHook
将有关 record 的信息存储到 records 中。仅在 shouldRecord 返回 truthy 值时触发。
recordsSyncHook
将 compilation 相关信息存储到 record 中。仅在 shouldRecord 返回 truthy 值时触发。
compilation recordsSyncHook
在创建模块 asset 之前执行。
SyncHook
为这些 chunk 创建其他 asset。
chunksSyncBailHook
调用以确定是否生成 chunk asset。返回任何 !== false 将允许生成 chunk asset。
SyncHook
在创建 chunk asset 之前。
AsyncSeriesHook
为 compilation 创建额外 asset。 这个钩子可以用来下载图像,例如:
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
优化所有 chunk asset。asset 存储在 compilation.assets 中。
每个 Chunk 都具有一个 files 属性,其指向由一个 chunk 创建的所有文件。
任何额外 chunk asset 都存储在 compilation.additionalChunkAssets 中。
chunksHere's an example that adds a banner to each chunk.
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
chunk asset 已经被优化。
chunks这里是一个来自 @boopathi 的示例插件,详细地输出每个 chunk 里有什么。
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 中的所有 asset。
assetsSyncHook
asset 已经优化。
assetsAsyncSeriesHook
asset 处理.
Hook 参数:
name: string — 插件名称stage: Stage — a stage to tap into (see the list of supported stages below)additionalAssets?: true | (assets, [callback]) => (void | Promise<void>) — a callback for additional assets (see below)回调参数:
assets: { [pathname: string]: Source } — 普通对象,其中 key 是 asset 的路径名,value 是 asset 的数据,具体的代表请参考 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 - 针对插件后续添加的 asset 执行回调。
在此模式下,回调将被多次调用:一次是在指定阶段之前添加资产时,另一次是后来由插件添加资产时。(在本阶段或下一阶段)。
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>) - 针对插件后续添加的 asset 执行指定的回调(在本阶段或下一阶段)。回调必须遵循所使用的 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
}
);如下是我们可以使用的 stage 清单(按顺序处理):
PROCESS_ASSETS_STAGE_ADDITIONAL — 在编译中添加额外的 asset。PROCESS_ASSETS_STAGE_PRE_PROCESS — asset 进行了基础预处理。PROCESS_ASSETS_STAGE_DERIVED — 从已有 asset 中获取新的 asset。PROCESS_ASSETS_STAGE_ADDITIONS — 为现有的 asset 添加额外的内容,例如 banner 或初始代码。PROCESS_ASSETS_STAGE_OPTIMIZE — 以通用的方式优化已有 asset。PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT — 优化现有资产的数量,例如,进行合并操作。PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY — 优化现有 asset 兼容性,例如添加 polyfills 或者 vendor prefixes。PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE — 优化现有 asset 大小,例如进行压缩或者删除空格。PROCESS_ASSETS_STAGE_DEV_TOOLING — 为 asset 添加开发者工具,例如,提取 source map。PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE 5.8.0+ — 优化已有 asset 数量,例如,通过将 asset 内联到其他 asset 中。PROCESS_ASSETS_STAGE_SUMMARIZE — 整理现有 asset 列表。PROCESS_ASSETS_STAGE_OPTIMIZE_HASH — 优化 asset 的 hash 值,例如,生成 asset 内容的真实 hash 值。PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER — 优化已有 asset 的转换操作,例如对 asset 进行压缩,并作为独立的 asset。PROCESS_ASSETS_STAGE_ANALYSE — 分析已有 asset。PROCESS_ASSETS_STAGE_REPORT — 创建用于上报的 asset。"asset info" 元数据不会自动提供给这个 hook。如果必须使用,你需要通过编译实例以及 asset 路径来手动获取这个元数据。这将在未来的 webpack 版本中得到改善。
Example:
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 hook 无错误执行后调用。
SyncBailHook
调用来决定 compilation 是否需要解除 seal 以引入其他文件。
AsyncSeriesHook
在 needAdditionalSeal 之后立即执行。
SyncHook
触发来为每个 chunk 生成 hash。
chunk chunkHashSyncHook
一个模块中的一个 asset 被添加到 compilation 时调用。
module filenameSyncHook
一个 chunk 中的一个 asset 被添加到 compilation 时调用。
chunk filenameSyncWaterfallHook
调用以决定 asset 的路径。
path optionsSyncBailHook
调用以决定 asset 在输出后是否需要进一步处理。
SyncHook
子 compiler 设置之后执行。
childCompiler compilerName compilerIndex从 webpack v5 开始,normalModuleLoader 钩子已经删除。现在要访问 loader 请改用 NormalModule.getCompilationHooks(compilation).loader。