背景
如今‘大前端’这个概念在前端界大热,说‘大前端’,我们就要提到‘前后端分离’,‘前后端分离’又离不开‘本地开发构建’,‘本地开发构建’自然离不开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;