外掛授予在 webpack 建置系統中執行自訂化的無限機會。這允許您建立自訂資產類型、執行獨特的建置修改,甚至在使用中間軟體時增強 webpack 執行時期。以下是撰寫外掛時會派上用場的一些 webpack 功能。
在編譯封裝後,可以遍歷編譯中的所有結構。
class MyPlugin {
apply(compiler) {
compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
// Explore each chunk (build output):
compilation.chunks.forEach((chunk) => {
// Explore each module within the chunk (built inputs):
chunk.getModules().forEach((module) => {
// Explore each source file path that was included into the module:
module.buildInfo &&
module.buildInfo.fileDependencies &&
module.buildInfo.fileDependencies.forEach((filepath) => {
// we've learned a lot about the source structure now...
});
});
// Explore each asset filename generated by the chunk:
chunk.files.forEach((filename) => {
// Get the asset source for each file generated by the chunk:
var source = compilation.assets[filename].source();
});
});
callback();
});
}
}
module.exports = MyPlugin;
compilation.modules
:編譯中的模組(建置輸入)集合。每個模組管理從來源程式庫建置原始檔案。module.fileDependencies
:包含在模組中的來源檔案路徑陣列。這包括來源 JavaScript 檔案本身(例如:index.js
),以及它已要求的所有依賴項資產檔案(樣式表、圖像等)。檢閱依賴項有助於瞭解哪些來源檔案屬於模組。compilation.chunks
:編譯中的區塊(建置輸出)集合。每個區塊管理最終呈現資產的組成。chunk.getModules()
:包含在區塊中的模組陣列。進一步來說,您可以瀏覽每個模組的依賴項,以查看哪些原始來源檔案提供給區塊。chunk.files
:由區塊產生的輸出檔名集合。您可以從 compilation.assets
表格存取這些資產來源。在執行 webpack 中間件時,每個編譯都包含一個 fileDependencies
Set
(正在監控的文件)和一個 fileTimestamps
Map
,將受監控的文件路徑對應到時間戳記。這些對於偵測編譯中有哪些文件已變更非常有用
class MyPlugin {
constructor() {
this.startTime = Date.now();
this.prevTimestamps = new Map();
}
apply(compiler) {
compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
const changedFiles = Array.from(compilation.fileTimestamps.keys()).filter(
(watchfile) => {
return (
(this.prevTimestamps.get(watchfile) || this.startTime) <
(compilation.fileTimestamps.get(watchfile) || Infinity)
);
}
);
this.prevTimestamps = compilation.fileTimestamps;
callback();
});
}
}
module.exports = MyPlugin;
您也可以將新的文件路徑提供給監視圖表,以便在這些文件變更時收到編譯觸發。將有效的檔案路徑新增到 compilation.fileDependencies
Set
中,以將它們新增到受監控的文件中。
與監視圖表類似,您可以透過追蹤區塊(或模組)的雜湊值,來監控編譯中已變更的區塊(或模組)。
class MyPlugin {
constructor() {
this.chunkVersions = {};
}
apply(compiler) {
compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
var changedChunks = compilation.chunks.filter((chunk) => {
var oldVersion = this.chunkVersions[chunk.name];
this.chunkVersions[chunk.name] = chunk.hash;
return chunk.hash !== oldVersion;
});
callback();
});
}
}
module.exports = MyPlugin;