背景
如今‘大前端’這個概念在前端界大熱,說‘大前端’,我們就要提到‘前后端分離’,‘前后端分離’又離不開‘本地開發構建’,‘本地開發構建’自然離不開webpack,webpack想要工作,那它就需要各種插件的支持,O(∩_∩)O哈哈~,逗了一大圈,終於引出了主題。
相信有不少童鞋在平時的項目開發中使用過Webpack Plugins,然而大部分人真是‘使用’啊(包括之前的我),只有少數人會去深究插件的原理與開發實踐;又逢今日讀到Webpack中文文檔《如何編寫一個插件》一節,所以在此做下插件開發的簡單介紹,反正我讀完這節后是豁然開朗了,不知道對大家有沒有幫助,文中如有錯誤,望踴躍指正!!
分析
1 /** 2 * webpack插件開發采用'動態原型模式' 3 * 插件開發,最重要的兩個對象:compiler、compilation 4 * @param options 5 * @constructor 6 */ 7 function MyPlugin(options) { // 根據 options 配置你的插件 8 9 } 10 // 我們可以在原型上添加一些方法 11 MyPlugin.prototype.someFunc = function() {/*something*/} 12 13 // apply方法是必須要有的,因為當我們使用一個插件時(new somePlugins({})),webpack會去尋找插件的apply方法並執行 14 MyPlugin.prototype.apply = function(compiler) { 15 // compiler是什么?compiler是webpack的'編譯器'引用 16 17 18 // compiler.plugin('***')和compilation.plugin('***')代表什么? 19 // document.addEventListener熟悉吧?其實是類似的 20 // compiler.plugin('***')就相當於給compiler設置了事件監聽 21 // 所以compiler.plugin('compile')就代表:當編譯器監聽到compile事件時,我們應該做些什么 22 23 // compile('編譯器'對'開始編譯'這個事件的監聽) 24 compiler.plugin("compile", function(params) { 25 console.log("The compiler is starting to compile..."); 26 }); 27 28 // compilation('編譯器'對'編譯ing'這個事件的監聽) 29 compiler.plugin("compilation", function(compilation) { 30 console.log("The compiler is starting a new compilation..."); 31 // 在compilation事件監聽中,我們可以訪問compilation引用,它是一個代表編譯過程的對象引用 32 // 我們一定要區分compiler和compilation,一個代表編譯器實體,另一個代表編譯過程 33 // optimize('編譯過程'對'優化文件'這個事件的監聽) 34 compilation.plugin("optimize", function() { 35 console.log("The compilation is starting to optimize files..."); 36 }); 37 }); 38 39 // emit('編譯器'對'生成最終資源'這個事件的監聽) 40 compiler.plugin("emit", function(compilation, callback) { 41 console.log("The compilation is going to emit files..."); 42 43 // compilation.chunks是塊的集合(構建后將要輸出的文件,即編譯之后得到的結果) 44 compilation.chunks.forEach(function(chunk) { 45 // chunk.modules是模塊的集合(構建時webpack梳理出的依賴,即import、require的module) 46 // 形象一點說:chunk.modules是原材料,下面的chunk.files才是最終的成品 47 chunk.modules.forEach(function(module) { 48 // module.fileDependencies就是具體的文件,最真實的資源【舉例,在css中@import("reset.css"),這里的reset.css就是fileDependencie】 49 module.fileDependencies.forEach(function(filepath) { 50 // 到這一步,就可以操作源文件了 51 }); 52 }); 53 54 // 最終生成的文件的集合 55 chunk.files.forEach(function(filename) { 56 // source()可以得到每個文件的源碼 57 var source = compilation.assets[filename].source(); 58 }); 59 }); 60 61 // callback在最后必須調用 62 callback(); 63 }); 64 }; 65 66 // 以上compiler和compilation的事件監聽只是一小部分,詳細API可見該鏈接http://www.css88.com/doc/webpack2/api/plugins/ 67 68 module.exports = MyPlugin;