创建自定义注册表
此功能允许将自定义注册表插入到任务系统中,从而提供共享任务或增强功能。注册表使用 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)
预先定义任务。
参数列表
参数 | 类型 | 备注 |
---|---|---|
gulpInst | object | gulp 的实例。 |
get(name)
get()
方法接收一个 name
参数,代表任务的名称,需要自定义注册表解析并返回对应的任务,如果不存在该名称所对应的任务,则返回 undefined
。
参数列表
参数 | 类型 | 备注 |
---|---|---|
name | string | 要获取的任务的名称。 |
set(name, fn)
set()
方法接收任务 name
和 fn
参数。该方法由 task()
在内部调用,用于向自定义注册表提供用户注册的任务。
参数列表
参数 | 类型 | 备注 |
---|---|---|
name | string | 要设置的任务的名称。 |
fn | function | 要设置的任务函数。 |
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();
}));
示例
- undertaker-registry: Gulp 4 的默认注册表。
- undertaker-common-tasks: 概念验证型自定义注册表,可预先定义任务。
- undertaker-task-metadata: 概念验证型自定义注册表,可为每个任务附加元数据。