在以前的文章中,咱們瞭解到了webpack的打包機制和loader,loader 用於轉換某些類型的模塊,而plugin則能夠用於執行範圍更廣的任務。包括:打包優化,資源管理,注入環境變量。插件目的在於解決 loader 沒法實現的其餘事。因此咱們頗有必要探究一下webpack的plugin機制。前端
在 Webpack 運行的生命週期中會廣播出許多事件,Plugin 能夠監聽這些事件,在合適的時機經過 Webpack 提供的 API 改變輸出結果。plugin是一個擴展器,在webpack打包的過程當中,基於事件驅動的機制,監聽webpack打包過程當中的某些節點,從而執行普遍的任務。webpack
一個插件由如下構成:git
首先是寫一個構造函數(此構造函數上的 prototype 對象具備 apply 方法),apply 方法能夠接收一個 webpack compiler 對象的引用,從而能夠在回調函數中訪問到 compiler 對象。再就是構造方法,接收配置中傳入的options(此構造方法根據須要可寫可不寫)。github
class ReadmeWebpackPlugin {
constructor(options) {
console.log(options)
}
apply(compiler){
}
}
module.exports = ReadmeWebpackPlugin;
複製代碼
插件的使用:在webpack.config.js中的plugins 數組中添加一個實例web
const ReadmetWebpackPlugin = require('./plugins/readme-webpack-plugin')
plugins:[
new ReadmetWebpackPlugin({
name:'hfj'
})
],
複製代碼
這裏傳入了一個參數,能夠在命令行看到是能夠打印出來的。數組
在插件開發中最重要的兩個資源就是 compiler 和 compilation 對象。理解它們的角色是擴展 webpack 引擎重要的第一步。bash
compiler能夠理解爲一個webpack的實例,該實例存儲了webpack配置、打包過程等一系列的內容。compiler提供了compiler.hooks,在爲 webpack 開發插件時,你可能須要知道每一個鉤子函數是在哪裏調用的,具體就能夠查閱官方文檔。這裏能夠看到有不少時刻,咱們能夠根據這些不一樣的時刻去讓插件作不一樣的事情。架構
compilation 模塊會被 compiler 用來建立新的編譯(或新的構建)。該實例存放的是本次打包編譯的內容。app
當咱們決定在在compiler的某個肯定的hooks寫一些事情的時候,會發現hooks裏有異步鉤子和同步鉤子,隨便舉幾個例子:異步
當爲AsyncSeriesHook時,咱們使用tapAsync來tap插件,須要注意,咱們須要調用 callback,此 callback 將做爲最後一個參數傳入函數。
如今我須要本身寫一個插件,在webpack打包結束後把一個readme.txt放到dist目錄。 首先須要知道,這是怎樣的時刻,是的,是在webpack打包結束後,生成資源到 output 目錄以前。 經過查看文檔中的complier hook。Very good!有emit這個hook!同時發現,這個emit是AsyncSeriesHook,異步的,因此記得上文提到過的,使用它的tapAsync方法,而且要回調函數。 思路已經很清晰了,代碼寫起來!
class ReadmeWebpackPlugin {
apply(compiler){
compiler.hooks.emit.tapAsync('ReadmeWebpackPlugin',( compilation,callback ) => {
console.log(compilation.assets)
compilation.assets['readme.txt'] = {
source:function(){
return 'readme'
},
size:function(){
return 6
}
}
callback()
})
}
}
module.exports = ReadmeWebpackPlugin;
複製代碼
上述代碼中打印了compilation.assets,打包後的內容有哪些是放在compilation的assets屬性中的,因此咱們能夠依照上述增長鍵值對的方式再增長一個文件。 用一下:
//webpack.config.js
...其餘配置,
plugins:[
new ReadmetWebpackPlugin()
],
複製代碼
成功:
若是你閱讀了webpack的源碼,你會發現,webpack中有很大的篇幅是基於plugin的機制編寫的,因此能夠說plugin是webapck的核心。好在咱們已經搞懂了webpack的plugin機制,已經能夠寫本身的插件了。