每個(gè) gulp 任務(wù)(task)都是一個(gè)異步的 JavaScript 函數(shù),此函數(shù)是一個(gè)可以接收 callback 作為參數(shù)的函數(shù),或者是一個(gè)返回 stream、promise、event emitter、child process 或 observable (后面會(huì)詳細(xì)講解)
類型值的函數(shù)。由于某些平臺(tái)的限制而不支持異步任務(wù),因此 gulp 還提供了一個(gè)漂亮 替代品。
任務(wù)(tasks)可以是 public(公開) 或 private(私有) 類型的。
一個(gè)私有(private)類型的任務(wù)(task)在外觀和行為上和其他任務(wù)(task)是一樣的,但是不能夠被用戶直接調(diào)用。如需將一個(gè)任務(wù)(task)注冊(cè)為公開(public)類型的,只需從 gulpfile 中導(dǎo)出(export)即可。
const { series } = require('gulp');
// `clean` 函數(shù)并未被導(dǎo)出(export),因此被認(rèn)為是私有任務(wù)(private task)。
// 它仍然可以被用在 `series()` 組合中。
function clean(cb) {
// body omitted
cb();
}
// `build` 函數(shù)被導(dǎo)出(export)了,因此它是一個(gè)公開任務(wù)(public task),并且可以被 `gulp` 命令直接調(diào)用。
// 它也仍然可以被用在 `series()` 組合中。
function build(cb) {
// body omitted
cb();
}
exports.build = build;
exports.default = series(clean, build);
在以前的 gulp 版本中,task() 方法用來將函數(shù)注冊(cè)為任務(wù)(task)。雖然這個(gè) API 依舊是可以使用的,但是 導(dǎo)出(export)將會(huì)是主要的注冊(cè)機(jī)制,除非遇到 export 不起作用的情況。
Gulp 提供了兩個(gè)強(qiáng)大的組合方法: series() 和 parallel(),允許將多個(gè)獨(dú)立的任務(wù)組合為一個(gè)更大的操作。這兩個(gè)方法都可以接受任意數(shù)目的任務(wù)(task)函數(shù)或已經(jīng)組合的操作。series() 和 parallel() 可以互相嵌套至任意深度。
如果需要讓任務(wù)(task)按順序執(zhí)行,請(qǐng)使用 series() 方法。
const { series } = require('gulp');
function transpile(cb) {
// body omitted
cb();
}
function bundle(cb) {
// body omitted
cb();
}
exports.build = series(transpile, bundle);
對(duì)于希望以最大并發(fā)來運(yùn)行的任務(wù)(tasks),可以使用 parallel() 方法將它們組合起來。
const { parallel } = require('gulp');
function javascript(cb) {
// body omitted
cb();
}
function css(cb) {
// body omitted
cb();
}
exports.build = parallel(javascript, css);
當(dāng) series() 或 parallel() 被調(diào)用時(shí),任務(wù)(tasks)被立即組合在一起。這就允許在組合中進(jìn)行改變,而不需要在單個(gè)任務(wù)(task)中進(jìn)行條件判斷。
const { series } = require('gulp');
function minify(cb) {
// body omitted
cb();
}
function transpile(cb) {
// body omitted
cb();
}
function livereload(cb) {
// body omitted
cb();
}
if (process.env.NODE_ENV === 'production') {
exports.build = series(transpile, minify);
} else {
exports.build = series(transpile, livereload);
}
series() 和 parallel() 可以被嵌套到任意深度。
const { series, parallel } = require('gulp');
function clean(cb) {
// body omitted
cb();
}
function cssTranspile(cb) {
// body omitted
cb();
}
function cssMinify(cb) {
// body omitted
cb();
}
function jsTranspile(cb) {
// body omitted
cb();
}
function jsBundle(cb) {
// body omitted
cb();
}
function jsMinify(cb) {
// body omitted
cb();
}
function publish(cb) {
// body omitted
cb();
}
exports.build = series(
clean,
parallel(
cssTranspile,
series(jsTranspile, jsBundle)
),
parallel(cssMinify, jsMinify),
publish
);
當(dāng)一個(gè)組合操作執(zhí)行時(shí),這個(gè)組合中的每一個(gè)任務(wù)每次被調(diào)用時(shí)都會(huì)被執(zhí)行。例如,在兩個(gè)不同的任務(wù)(task)之間調(diào)用的 clean 任務(wù)(task)將被執(zhí)行兩次,并且將導(dǎo)致不可預(yù)期的結(jié)果。因此,最好重構(gòu)組合中的 clean 任務(wù)(task)。
如果你有如下代碼:
// This is INCORRECT
const { series, parallel } = require('gulp');
const clean = function(cb) {
// body omitted
cb();
};
const css = series(clean, function(cb) {
// body omitted
cb();
});
const javascript = series(clean, function(cb) {
// body omitted
cb();
});
exports.build = parallel(css, javascript);
重構(gòu)為:
const { series, parallel } = require('gulp');
function clean(cb) {
// body omitted
cb();
}
function css(cb) {
// body omitted
cb();
}
function javascript(cb) {
// body omitted
cb();
}
exports.build = series(clean, parallel(css, javascript));
更多建議: