这是一个系列的文章,目前一共有3篇,是原做者在去年开始连载的系列教程, 我看了一下没看太懂, 翻译出来,你们探讨一下, 这个是第二部分, 第一部分是webpack 的各个包的功能介绍.就不翻译了.想看的就按原文连接 你就能找到所有的系列vue
就算这篇教程和上一篇教程都是关于如何向webpack贡献代码的,可是我想先花费一些时间给大家说一下你将会在不少项目中看见的范例(不少项目指的应该是 webpack 里面分布的包)webpack
注意: 对于想向webpack 贡献代码的小伙伴, 或者想本身写插件的小伙伴,这对大家尤为有用.git
就像上一部分说的,tapable 是webpack 的核心构建块,(webpack是又不少个块组成的),类和对象都继承tapable是tapable 的实例,下面有一个很是简单的例子.github
const Tapable = require('tapable'); class Compiler extends Tapable { constructor() { this.foo = "43"; this.applyPluginsAsync("run", this, function(err, done) { if (done) {this.doRunStuffAfterSuccess()} } this.applyPlugins("done", stats); } }
tapable 添加了插件能够挂钩进去的事件触发功能, 你能够在你使用的任何webpack库中搜索this.applyPlugins 找到挂钩的事件.(通常是插件源码)web
一个webpack 插件的样子最好描述成一个实现了 apply() 方法的类,这个方法会在tapable 实例(一般指Compiler)的初始化事件钩子中被调用,体验一下下面的例子.设计模式
class MyFirstPlugin { apply(compiler) { compiler.plugin("run", function(compiler, cb) { console.log("webpack is about to start bundling"); cb(); // cb() signals to the compiler that this asnyc hook is finished. }); compiler.plugin("done", function(stats) { console.log("webpack is finished bundling"); }); } }
这里有几个关键的点架构
.plugins
函数,而后指定事件的名字,和一个执行你的逻辑的回调.tapable实例经过调用apply方法,传入一个nwe 出来的插件实例来注册插件,例如,若是咱们要注册上面的插件,咱们只须要这样写,compiler.apply(new MyFirstPlugin())
app
webpack 的插件都是设计成单一目的的,也就是一个插件只能有一个功能.观察下面的代码;异步
var SingleEntryPlugin = require("./SingleEntryPlugin"); var MultiEntryPlugin = require("./MultiEntryPlugin"); function EntryOptionPlugin() {} module.exports = EntryOptionPlugin; EntryOptionPlugin.prototype.apply = function(compiler) { compiler.plugin("entry-option", function(context, entry) { function itemToPlugin(item, name) { if(Array.isArray(item)) return new MultiEntryPlugin(context, item, name); else return new SingleEntryPlugin(context, item, name); } if(typeof entry === "string" || Array.isArray(entry)) { compiler.apply(itemToPlugin(entry, "main")); } else if(typeof entry === "object") { Object.keys(entry).forEach(function(name) { compiler.apply(itemToPlugin(entry[name], name)); }); } return true; }); };
EntryOptionPlugin’s
惟一的目的就是要钩(这里的勾是钩子函数的概念)进去compiler实例,以得到全部在配置文件里面定义的对象的入口点,而后转换为SingleEntryPlugin
实例 或者MultiEntryPlugin
实例的值,而后把这些插件传递回compiler.aaply()
去注册他们.函数
学习源码,写你本身的插件,问问题,作笔记,使用这些难以置信(估计做者在这里幽默了一番,这些方法并不难以执行)的方法,你不只能学会属于本身的技能,还可让你成为webpack的下一个贡献者,最后在一天结束的时候,感到颇有趣.
如今你在webpack 和他的插件系统如何工做上有必定的了解,让咱们来看一下被webpack 使用的tapable.
run
和 emit
这样的事件.Compiler
类返回Compilation‘s
, 这是你的应用的依赖图的入口,Compilation
包含了optimize-modules
, seal
and optimize-chunk-assets
这样的钩子,全部的优化,和总体程序的编译,和工具,都会在Compilation
执行..
这个插件建立的.插入webpack解析器的插件,是用于定制模块解析策略(详情请了解策略模式)的,你的webpack的配置的resolve
对象的全部属性对应于已经应用的指定的插件解析器.resolver
, loader
和 NormalModule
的建立物绑定在一块儿,你会用到的生命周期钩子包括before-resolve
, after-resolve
, 和 create-module
, 除此以外,loaders 针对每个模块运行,他能够从他们的原的文件,转换成能够被添加进入webpack的 chunk
的东西(例如vue-loader 就会把vue文件转换成 对象)MainTemplate
(运行时 绑定(bundle)包装器), ChunkTemplate
等等....(这里我建议大家看原版吧,实在翻译不出)acorn
ast 分析器 提供功能的tapable 实例.前面全部的类均可以发出Tapable事件所以能够为他们编写插件.
译者注: 原文下面都是一些让你努力学习,每天向上,让你选择一个源码去看,而后是最紧要系你以为开心,之类的话,我选择不译.
tapable 库已经通过更新, 上面提到的方法已经废弃了,可是基本架构并无改变, 具体请关注github的tapable仓库