Skip to main content

创建自定义注册表

此功能允许将自定义注册表插入到任务系统中,从而提供共享任务或增强功能。注册表使用 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)格式
class TestRegistry {
init(gulpInst) {}

get(name) {}

set(name, fn) {}

tasks() {}
}

如果传递给 registry() 函数的注册表实例不具备全部四个方法,就会报错。

注册

如果我们要将上面的示例注册表进行注册,就需要向 registry() 函数传递一个注册表实例。

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

// ... TestRegistry setup code

// good!
registry(new TestRegistry())

// bad!
registry(TestRegistry())
// This will trigger an error: '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) {
// do things
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);
// Preserve internal properties and task metadata.
var task = Object.assign(bound, fn);
// The `DefaultRegistry` uses `this._tasks` for storage.
this._tasks[name] = task;
return task;
};

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

// `registry` will reset each task in the registry with
// `ConfigRegistry.prototype.set` which will bind them to the config object.
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();
}));

示例