跳到主要内容

创建自定义注册表

允许将自定义注册表插入到任务系统中,可以提供共享任务或增强功能。注册表使用 registry() 进行注册。

结构​

为了被 gulp 接受,自定义注册表必须遵循特定格式。

// 作为函数
function TestRegistry() {}

TestRegistry.prototype.init = function (gulpInst) {}
TestRegistry.prototype.get = function (name) {}
TestRegistry.prototype.set = function (name, fn) {}
TestRegistry.prototype.tasks = function () {}

// 作为类
class TestRegistry {
init(gulpInst) {}

get(name) {}

set(name, fn) {}

tasks() {}
}

如果传递给 registry() 的注册表实例没有全部四个方法,将抛出错误。

注册​

如果我们想注册上面的示例注册表,我们需要将其实例传递给 registry()。

const { registry } = require('gulp');

// ... TestRegistry 设置代码

// 正确!
registry(new TestRegistry())

// 错误!
registry(TestRegistry())
// 这将触发错误:'Custom registries must be instantiated, but it looks like you passed a constructor'

方法​

init(gulpInst)​

注册表的 init() 方法在 registry() 函数的最后被调用。作为唯一参数传递的 gulp 实例(gulpInst)可用于使用 gulpInst.task(taskName, fn) 预定义任务。

参数​

参数类型说明
gulpInstobjectgulp 的实例。

get(name)​

get() 方法接收一个任务 name,供自定义注册表解析并返回,如果不存在具有该名称的任务,则返回 undefined。

参数​

参数类型说明
namestring要检索的任务名称。

set(name, fn)​

set() 方法接收任务 name 和 fn。这是由 task() 内部调用,以向自定义注册表提供用户注册的任务。

参数​

参数类型说明
namestring要设置的任务名称。
fnfunction要设置的任务函数。

tasks()​

必须返回一个对象,列出注册表中的所有任务。

使用场景​

共享任务​

要与所有项目共享通用任务,可以在注册表上公开 init 方法,它将接收 gulp 实例作为唯一参数。然后,你可以使用 gulpInst.task(name, fn) 注册预定义的任务。

例如,你可能想要共享一个 clean 任务:

const fs = require('fs');
const util = require('util');

const DefaultRegistry = require('undertaker-registry');
const del = require('del');

function CommonRegistry(opts){
DefaultRegistry.call(this);

opts = opts || {};

this.buildDir = opts.buildDir || './build';
}

util.inherits(CommonRegistry, DefaultRegistry);

CommonRegistry.prototype.init = function(gulpInst) {
const buildDir = this.buildDir;
const exists = fs.existsSync(buildDir);

if(exists){
throw new Error('Cannot initialize common tasks. ' + buildDir + ' directory exists.');
}

gulpInst.task('clean', function(){
return del([buildDir]);
});
}

module.exports = CommonRegistry;

然后在项目中使用它:

const { registry, series, task } = require('gulp');
const CommonRegistry = require('myorg-common-tasks');

registry(new CommonRegistry({ buildDir: '/dist' }));

task('build', series('clean', function build(cb) {
// 做一些事情
cb();
}));

共享功能​

通过控制如何将任务添加到注册表,你可以装饰它们。

例如,如果你希望所有任务共享某些数据,可以使用自定义注册表将它们绑定到该数据。确保返回更改后的任务,如上面注册表方法的描述所示:

const { registry, series, task } = require('gulp');
const util = require('util');
const DefaultRegistry = require('undertaker-registry');

// 在其他地方定义的一些任务
const BuildRegistry = require('./build.js');
const ServeRegistry = require('./serve.js');

function ConfigRegistry(config){
DefaultRegistry.call(this);
this.config = config;
}

util.inherits(ConfigRegistry, DefaultRegistry);

ConfigRegistry.prototype.set = function set(name, fn) {
var bound = fn.bind(this.config);
// 保留内部属性和任务元数据。
var task = Object.assign(bound, fn);
// `DefaultRegistry` 使用 `this._tasks` 进行存储。
this._tasks[name] = task;
return task;
};

registry(new BuildRegistry());
registry(new ServeRegistry());

// `registry` 将使用 `ConfigRegistry.prototype.set` 重置注册表中的每个任务,
// 这将使它们绑定到配置对象。
registry(new ConfigRegistry({
src: './src',
build: './build',
bindTo: '0.0.0.0:8888'
}));

task('default', series('clean', 'build', 'serve', function(cb) {
console.log('Server bind to ' + this.bindTo);
console.log('Serving' + this.build);
cb();
}));

示例​