跳到主要内容

创建自定义注册表

允许将自定义注册表插入到任务系统中,可以提供共享任务或增强功能。注册表使用 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() 方法接收任务 namefn。这是由 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();
}));

示例