Skip to content

Tapable API 文档及使用教程 #23

@noneven

Description

@noneven

Tapable API 文档及使用教程

Tapable(0.2.x)

使用

import Tapable from 'tapable';
//var Tapable = require('tapable');

Tapable 是一个用于事件发布订阅执行的插件架构。
在使用时你仅仅需要像这样继承它:

function MyClass() {
  Tapable.call(this);
}
MyClass.prototype = Object.create(Tapable.prototype);

// 或者这样
function MyClass2() {
  Tapable.call(this);
}
Tapable.mixin(MyClass2.prototype);

// 或者这样
class MyClass3 extends Tapable {
  constructor() {
    // TODO
  }
}

API

静态方法(Static functions)

  • mixin
void mixin(obj: Object)

复制 Tapable 的原型方法到目标对象

实例公共方法(Public functions)

  • apply

插件加载函数

void apply(plugin1: Plugin, plugin2: Plugin...)

通过 arguments 获得所有传入的插件对象,并调用插件对象的 apply 方法,注册插件(所以,一个合法的插件应该包含入口方法 apply)

  • plugin

事件绑定函数,类似于 EventEmitter 的 on 方法

void plugin(names: string|string[], handler: Function)

names: 需要监听的事件名称,可以传入事件名称集合(同时绑定多个事件),也可以传入单个事件名称
handler: 事件的处理函数

例子1:

var Tapable = require('tapable');

function Compiler(plugins) {
  Tapable.call(this);
  // 注册插件
  this.apply(...plugins);
  // 编译器在某个异步操作完成后触发事件
  setTimeout(() => {
    // 触发事件
    this.applyPlugins('compiled', 'test');
  }, 4000);
}
Compiler.prototype = Object.create(Tapable.prototype);

function CustomPlugin() {}
CustomPlugin.prototype.apply = function (compiler) {
  // 注册插件时会调用插件的 apply 方法,会执行绑定插件
  compiler.plugin('compiled', (arg) => {
    console.log('arg:', arg); // arg: test
  });
};

new Compiler([new CustomPlugin()]);

实例受保护方法(Protected functions)

  • applyPlugins

类似 EventEmitter 的 emit 方法,使用实例见例子1

void applyPlugins(name: string, args: any...)

触发事件 name,传入参数 args,并行调用所有注册在事件 name 上的处理函数。

  • applyPluginsWaterfall
any applyPluginsWaterfall(name: string, init: any, args: any...)

触发事件 name,串行的调用注册在事件 name 上的处理函数(先入先出),最先执行的处理函数传入 init 和 args,后续的处理函数传入前一个处理函数的返回值和 args,函数最终返回最后一个处理函数的返回结果
例子2:【后面的例子可以由这个例子修改观察结果】

var Tapable = require('tapable');

function Compiler(plugins) {
  Tapable.call(this);
  // 注册插件
  this.apply(...plugins);
  // 编译器在某个异步操作完成后触发事件
  setTimeout(() => {
    // 触发事件
    const afterPluginValue = this.applyPluginsWaterfall('compiled', 'InitValue');
    console.log('after all plugins value:', afterPluginValue);
  }, 4000);
}
Compiler.prototype = Object.create(Tapable.prototype);

function CustomPlugin() {}
CustomPlugin.prototype.apply = function (compiler) {
  // 注册插件时会调用插件的 apply 方法,会执行绑定插件
  compiler.plugin('compiled', (arg) => {
    console.log('in plugin value:', arg);
    // todo
    console.log('out plugin value:', 'PluginValue');
    return 'PluginValue';
  });
};
function CustomPlugin1() {}
CustomPlugin1.prototype.apply = function (compiler) {
  // 注册插件时会调用插件的 apply 方法,会执行绑定插件
  compiler.plugin('compiled', (arg) => {
    console.log('in plugin1 value::', arg);
    // todo
    console.log('out plugin1 value:', 'PluginValue1');
    return 'Plugin1Value';
  });
};

new Compiler([new CustomPlugin(), new CustomPlugin1()]);

// in plugin value: InitValue
// out plugin value: PluginValue
// in plugin1 value:: PluginValue
// out plugin1 value: PluginValue1
// after all plugins value: Plugin1Value
  • applyPluginsAsyncWaterfall
applyPluginsAsyncWaterfall(
  name: string,
  init: any,
  callback: (err: Error, result: any) -> void
)

触发事件 name,串行的调用注册在 name 上的处理函数(先入先出),第一个处理函数传入参数 init,后续的函数依赖于前一个函数执行回调的时候传入的参数nextValue,倘若某一个处理函数报错,则执行传入的 callback(err),后续的处理函数将不被执行,否则最后一个处理函数调用 callback(value)
注意:插件注册此类事件,处理函数需要调用 callback(err, nextValue),这样才能保证监听链的正确执行

var myPlugin = function() {}
myPlugin.prototype.apply(tapable) {
  tapable.plugin('name', function(arg1, ..., argn, callback)) {
    // todo
    // ...
    // 调用 callback
    callback(null, value);
  }
}
  • applyPluginsAsync = applyPluginsAsyncSeries
void applyPluginsAsync(
  name: string,
  args: any...,
  callback: (err?: Error) -> void
)

触发事件 name,串行的调用注册在事件 name 上的处理函数(先入先出),倘若某一个处理函数报错,则执行传入的 callback(err),后续的处理函数将不被执行,否则最后一个处理函数调用 callback。
注意:插件注册此类事件,处理函数需要调用callback,这样才能保证监听链的正确执行

var myPlugin = function() {}
myPlugin.prototype.apply(tapable) {
  tapable.plugin('name', function(arg1, ..., argn, callback)) {
    // todo
    // ...
    // 调用callback
    callback();
  }
}
  • applyPluginsBailResult
any applyPluginsBailResult(name: string, args: any...)

触发事件 name,串行的调用注册在事件 name 上的处理函数(先入先出),传入参数 args,如果其中一个处理函数返回值 !== undefined,直接返回这个返回值,后续的处理函数将不被执行

  • applyPluginsParallel
applyPluginsParallel(
  name: string,
  args: any...,
  callback: (err?: Error) -> void
)

触发事件 name,传入参数 args,并行的调用所有注册在事件 name 上的处理函数,倘若任一处理函数执行报错,则执行 callback('err'),否则当所有的处理函数都执行完的时候调用 callback()

同样,插件注册此类事件的时候,回调函数要执行 callback

  • applyPluginsParallelBailResult
applyPluginsParallelBailResult(
  name: string,
  args: any...,
  callback: (err: Error, result: any) -> void
)

触发事件 name,串行的执行注册在事件 name 上的处理函数(先入先出),每个处理函数必须调用 callback(err, result),倘若任一处理函数在调用callback(err, result) 的时候,err !== undefined || result !== undefined,则 callback 将真正被执行,后续的处理函数则不会再被执行。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions