?Compilation
? 模塊會被 ?Compiler
? 用來創(chuàng)建新的 compilation 對象(或新的 build 對象)。 ?compilation
? 實例能夠訪問所有的模塊和它們的依賴(大部分是循環(huán)依賴)。 它會對應(yīng)用程序的依賴圖中所有模塊, 進(jìn)行字面上的編譯(literal compilation)。 在編譯階段,模塊會被加載(load)、封存(seal)、優(yōu)化(optimize)、
分塊(chunk)、哈希(hash)和重新創(chuàng)建(restore)。
?Compilation
? 類擴展(extend)自 ?Tapable
?,并提供了以下生命周期鉤子。 可以按照 compiler 鉤子的相同方式來調(diào)用 tap:
compilation.hooks.someHook.tap(/* ... */);
和 ?compiler
? 用法相同,取決于不同的鉤子類型, 所以也可以在某些鉤子上訪問 ?tapAsync
? 和 ?tapPromise
?。
SyncHook
在模塊構(gòu)建開始之前觸發(fā),可以用來修改模塊。
module
?compilation.hooks.buildModule.tap(
'SourceMapDevToolModuleOptionsPlugin',
(module) => {
module.useSourceMap = true;
}
);
SyncHook
在重新構(gòu)建一個模塊之前觸發(fā)。
module
?SyncHook
模塊構(gòu)建失敗時執(zhí)行。
module error
?SyncHook
模塊構(gòu)建成功時執(zhí)行。
module
?AsyncSeriesHook
所有模塊都完成構(gòu)建并且沒有錯誤時執(zhí)行。
modules
?SyncHook
一個模塊完成重新構(gòu)建時執(zhí)行,在都成功或有錯誤的情況下。
module
?SyncHook
compilation 對象停止接收新的模塊時觸發(fā)。
SyncHook
compilation 對象開始接收新模塊時觸發(fā)。
SyncBailHook
依賴優(yōu)化開始時觸發(fā)。
modules
?SyncHook
依賴優(yōu)化之后觸發(fā)。
modules
?SyncHook
優(yōu)化階段開始時觸發(fā)。
SyncBailHook
在模塊優(yōu)化階段開始時調(diào)用。插件可以 tap 此鉤子對模塊進(jìn)行優(yōu)化。
modules
?SyncHook
在模塊優(yōu)化完成之后調(diào)用。
modules
?SyncBailHook
在 chunk 優(yōu)化階段開始時調(diào)用。插件可以 tap 此鉤子對 chunk 執(zhí)行優(yōu)化。
chunks
?SyncHook
chunk 優(yōu)化完成之后觸發(fā)。
chunks
?AsyncSeriesHook
在優(yōu)化依賴樹之前調(diào)用。插件可以 tap 此鉤子執(zhí)行依賴樹優(yōu)化。
chunks
? ?modules
?SyncHook
在依賴樹優(yōu)化成功完成之后調(diào)用。
chunks
? ?modules
?SyncBailHook
在樹優(yōu)化之后,chunk 模塊優(yōu)化開始時調(diào)用。插件可以 tap 此鉤子來執(zhí)行 chunk 模塊的優(yōu)化。
chunks
? ?modules
?SyncHook
在 chunk 模塊優(yōu)化成功完成之后調(diào)用。
chunks
? ?modules
?SyncBailHook
調(diào)用來決定是否存儲 record。返回任何內(nèi)容 ?!== false
? 將阻止執(zhí)行所有其他 "record" 鉤子(?record
?,? recordModules
?, ?recordChunks
? 和 ?recordHash
?)。
SyncHook
從 record 中恢復(fù)模塊信息。
modules
? ?records
?SyncHook
在為每個模塊分配 ?id
? 之前執(zhí)行。
modules
?SyncHook
調(diào)用來每個模塊分配一個 ?id
?。
modules
?SyncHook
在模塊 ?id
? 優(yōu)化開始時調(diào)用。
modules
?SyncHook
在模塊 ?id
? 優(yōu)化完成時調(diào)用。
modules
?SyncHook
從 record 中恢復(fù) chunk 信息。
chunks
? ?records
?SyncHook
在為每個 chunk 分配 ?id
? 之前執(zhí)行。
chunks
???SyncHook??
調(diào)用時,會為每個 chunk 分配一個 ?id
?。
chunks
?SyncHook
在 chunk ?id
? 優(yōu)化階段開始時調(diào)用。
chunks
?SyncHook
chunk ?id
? 優(yōu)化結(jié)束之后觸發(fā)。
chunks
?SyncHook
將模塊信息存儲到 record 中。?shouldRecord
? 返回 truthy 值時觸發(fā)。
modules
? ?records
?SyncHook
將 chunk 存儲到 record 中。?shouldRecord
? 返回 truthy 值時觸發(fā)。
chunks
? ?records
?SyncHook
在創(chuàng)建模塊哈希(hash)之前。
syncHook
在創(chuàng)建模塊哈希(hash)之后。
SyncHook
在 compilation 添加哈希(hash)之前。
SyncHook
在 compilation 添加哈希(hash)之后。
SyncHook
將有關(guān) record 的信息存儲到 ?records
? 中。僅在 ?shouldRecord
? 返回 truthy 值時觸發(fā)。
records
?SyncHook
將 compilation 相關(guān)信息存儲到 ?record
? 中。僅在 ?shouldRecord
? 返回 truthy 值時觸發(fā)。
compilation
? ?records
?SyncHook
在創(chuàng)建模塊 asset 之前執(zhí)行。
SyncHook
為這些 chunk 創(chuàng)建其他 asset。
chunks
?SyncBailHook
調(diào)用以確定是否生成 chunk asset。返回任何 ?!== false
? 將允許生成 chunk asset。
SyncHook
在創(chuàng)建 chunk asset 之前。
AsyncSeriesHook
為 compilation 創(chuàng)建額外 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
優(yōu)化所有 chunk asset。asset 存儲在 ?compilation.assets
? 中。 每個 ?Chunk
? 都具有一個 ?files
? 屬性,其指向由一個 chunk 創(chuàng)建的所有文件。 任何額外 chunk asset 都存儲在 ?compilation.additionalChunkAssets
? 中。
chunks
?Here'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 已經(jīng)被優(yōu)化。
chunks
?這里是一個來自 @boopathi 的示例插件,詳細(xì)地輸出每個 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
優(yōu)化存儲在 ?compilation.assets
? 中的所有 asset。
assets
??SyncHook
?
asset 已經(jīng)優(yōu)化。
assets
??AsyncSeriesHook
?
asset 處理.
Hook 參數(shù):
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)回調(diào)參數(shù):
assets: { [pathname: string]: Source }
?— 普通對象,其中 key 是 asset 的路徑名,value 是 asset 的數(shù)據(jù)。示例:
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 的函數(shù)作為參數(shù):
在此模式下,回調(diào)將被多次調(diào)用:一次是在指定階段之前添加資產(chǎn)時,另一次是后來由插件添加資產(chǎn)時。(在本階段或下一階段)。
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
}
);
2. ?(assets, [callback]) => (void | Promise<void>)
? - 針對插件后續(xù)添加的 asset 執(zhí)行指定的回調(diào)(在本階段或下一階段)?;卣{(diào)必須遵循所使用的 tap 函數(shù)的類型(例如,當(dāng)與? tapPromise()
? 一同使用時,它應(yīng)該返回一個 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
}
);
資產(chǎn)處理 stage 的列表
如下是我們可以使用的 stage 清單(按順序處理):
PROCESS_ASSETS_STAGE_ADDITIONAL
? — 在編譯中添加額外的 asset。PROCESS_ASSETS_STAGE_PRE_PROCESS
? — asset 進(jìn)行了基礎(chǔ)預(yù)處理。PROCESS_ASSETS_STAGE_DERIVED
? — 從已有 asset 中獲取新的 asset。PROCESS_ASSETS_STAGE_ADDITIONS
? — 為現(xiàn)有的 asset 添加額外的內(nèi)容,例如 banner 或初始代碼。PROCESS_ASSETS_STAGE_OPTIMIZE
? — 以通用的方式優(yōu)化已有 asset。PROCESS_ASSETS_STAGE_OPTIMIZE_COUNT
? — 優(yōu)化現(xiàn)有資產(chǎn)的數(shù)量,例如,進(jìn)行合并操作。PROCESS_ASSETS_STAGE_OPTIMIZE_COMPATIBILITY
? — 優(yōu)化現(xiàn)有 asset 兼容性,例如添加 polyfills 或者 vendor prefixes。PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE
? — 優(yōu)化現(xiàn)有 asset 大小,例如進(jìn)行壓縮或者刪除空格。PROCESS_ASSETS_STAGE_DEV_TOOLING
? — 為 asset 添加開發(fā)者工具,例如,提取 source map。PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE
? 5.8.0+ — 優(yōu)化已有 asset 數(shù)量,例如,通過將 asset 內(nèi)聯(lián)到其他 asset 中。PROCESS_ASSETS_STAGE_SUMMARIZE
? — 整理現(xiàn)有 asset 列表。PROCESS_ASSETS_STAGE_OPTIMIZE_HASH
? — 優(yōu)化 asset 的 hash 值,例如,生成 asset 內(nèi)容的真實 hash 值。PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER
? — 優(yōu)化已有 asset 的轉(zhuǎn)換操作,例如對 asset 進(jìn)行壓縮,并作為獨立的 asset。PROCESS_ASSETS_STAGE_ANALYSE
? — 分析已有 asset。PROCESS_ASSETS_STAGE_REPORT
? — 創(chuàng)建用于上報的 asset。"asset info" 元數(shù)據(jù)不會自動提供給這個 hook。如果必須使用,你需要通過編譯實例以及 asset 路徑來手動獲取這個元數(shù)據(jù)。這將在未來的 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 無錯誤執(zhí)行后調(diào)用。
SyncBailHook
調(diào)用來決定 compilation 是否需要解除 seal 以引入其他文件。
AsyncSeriesHook
在 ?needAdditionalSeal
? 之后立即執(zhí)行。
SyncHook
觸發(fā)來為每個 chunk 生成 hash。
chunk
? ?chunkHash
?SyncHook
一個模塊中的一個 asset 被添加到 compilation 時調(diào)用。
module
? ?filename
?SyncHook
一個 chunk 中的一個 asset 被添加到 compilation 時調(diào)用。
chunk
? ?filename
?SyncWaterfallHook
調(diào)用以決定 asset 的路徑。
path
? ?options
?SyncBailHook
調(diào)用以決定 asset 在輸出后是否需要進(jìn)一步處理。
SyncHook
子 compiler 設(shè)置之后執(zhí)行。
childCompiler
? ?compilerName
? ?compilerIndex
?從 webpack v5 開始,?normalModuleLoader
? 鉤子已經(jīng)刪除?,F(xiàn)在要訪問 loader 請改用 ?NormalModule.getCompilationHooks(compilation).loader
?。
更多建議: