目錄
- 一. plugin概述
- 1.1 Plugin的作用
- 1.2 Compiler
- 1.3 Compilation
- 二. 如何寫一個plugin
- 四. 實戰
- 【參考】
一. plugin概述
1.1 Plugin的作用
plugin機制是webpack中另一個核心概念,它基于事件流框架tapable,你可以參考瀏覽器環境中的【DOM事件模型】,【SPA模型中的生命周期鉤子】或是node環境中的【EventEmitter模塊】來理解其作用,plugin系統提供給開發者監聽webpack生命周期并在特定事件觸發時執行指定操作的能力,
當然,要寫一個真正能實作一定功能的插件,你還需要了解Compiler和Compilation這兩個概念,網上可以找到非常多相關的文章(《webpack-docs/plugin》),
1.2 Compiler
從表現上看,Compiler暴露了和webpack整個生命周期相關的鉤子,通過如下的方式訪問:
//基本寫法
compiler.hooks.someHook.tap(...)
//如果希望在entry配置完畢后執行某個功能
compiler.hooks.entryOption.tap(...)
//如果希望在生成的資源輸出到output指定目錄之前執行某個功能
compiler.hooks.emit.tap(...)
webpack在重要的生命周期節點上都提供了事件鉤子,我們可以借此加入一些自定義的功能,我們來撰寫一個插件,直觀地看看webpack中涉及的鉤子:
//check-compiler-hooks-plugin.js
const pluginName = 'checkCompilerHooksPlugin';
module.exports = class checkCompilerHooksPlugin {
apply(compiler){
//列印出entryOption執行完畢時Compiler暴露的鉤子
for(var hook of Object.keys(compiler.hooks)){
console.log(hook);
}
}
}
可以看到Compiler上可以使用的鉤子(當然這種方式看到的鉤子和實際觸發順序無關):

注意上圖中Compiler.hooks暴露的事件鉤子中有一個compilation,下一小節將解釋它,
1.3 Compilation
Compilation暴露了與模塊和依賴有關的粒度更小的事件鉤子,官方檔案中的說法是模塊會經歷加載(loaded),封存(sealed),優化(optimized),分塊(chunked),哈希(hashed)和重新創建(restored)這幾個典型步驟,從上面的示例可以看到,compilation是Compiler生命周期中的一個步驟,使用compilation相關鉤子的通用寫法為:
compiler.hooks.compilation.tap('SomePlugin',function(compilation, callback){
compilation.hooks.someOtherHook.tap('SomeOtherPlugin',function(){
....
})
});
我們仿照上面的方法就可以查看到compilation物件上(compilation事件觸發時,在回呼函式中取得的參考)暴露的事件鉤子,
Compiler和Compilation暴露的事件鉤子總數超過30個,具體資訊可以直接在官方檔案直接查詢API,在特定的階段鉤入想要添加的自定義功能,想要更好地理解
plugin的作用機制,還需要了解webpack的整個生命周期以及事件流框架tapable.
二. 如何寫一個plugin
根據webpack官方檔案的說明,一個自定義的plugin需要包含:
- 一個javascript命名函式
- 插件函式的prototype上要有一個
apply方法 - 指定一個系結到webpack自身的事件鉤子
- 注冊一個回呼函式來處理webpack實體中的指定資料
- 處理完成后呼叫webpack提供的回呼
官網給出了一個基本的結構示例:
//console-log-on-build-webpack-plugin.js
const pluginName = 'ConsoleLogOnBuildWebpackPlugin';
class ConsoleLogOnBuildWebpackPlugin {
apply(compiler){
compiler.hooks.run.tap(pluginName, compilation=>{
console.log('webpack構建程序開始');
});
}
}
將其添加到webpack插件中后可以看到運行中觸發了傳入的回呼函式:

四. 實戰
在《webpack4.0各個擊破(4)——javascript & splitChunks》一文中,我們使用splitChunks功能對初始模塊進行代碼分割,在為多頁面應用模型的html入口插入script標簽時遇到了無法自動插入的問題,那么本節我們用一個webpack-dispatch-chunk-plugin來解決一下這個問題,

處理的邏輯就是利用html-webpack-plugin暴露的更改資源標簽的事件鉤子htmlWebpackPluginAlterAssetTags來進行資源處理,此時資源已經離過模塊化和代碼分割并已經在名稱中加入了hash標記,只需要此時過濾掉名稱中含有vendors且不包含相應入口名稱的新的chunk即可,當然這只是一個基本功能,想要動態實作功能,還需要將上例中checkMap部分變為對Compiler或是Compilation上對應屬性的參考,本篇不再贅述,
【參考】
[1] webpack之內部運行機制》
作者:大史不說話
鏈接:Webpack4.0各個擊破(7)plugin篇
來源:博客園
著作權歸作者所有,商業轉載請聯系作者獲得授權,非商業轉載請注明出處,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/243193.html
標籤:JavaScript
