这是Gulp中人们经常遇到的共同问题,特别是那些从Grunt转换而来的人。Gulp是异步的极致,它总是想尽可能同时完成尽可能多的任务。
让任务按顺序运行的第一步是让gulp知道何时您的任务结束,有几种不同的方法可以实现这一点。
1)返回一个流,gulp将等待流的“end”事件作为该任务完成的触发器。例如:
gulp.task( "stream-task", function(){
return gulp.src( srcGlob )
.pipe(sass())
.pipe(compressCSS())
.pipe(gulp.dest( destGlob ));
});
2) 返回一个Promise,gulp将等待Promise进入已解决状态,然后才会将任务标记为完成。例如:(不完美,只是为了说明问题)
gulp.task( "promise-task", function() {
return new Promise(function(resolve, reject){
fs.readFile( "filename", function( err, data ){
if( err ){ return reject(err); }
return resolve( data );
});
});
});
3) 如果函数没有返回任何内容,但函数签名需要一个参数,则调用任务回调函数。该参数将是一个回调函数,您可以调用它来表示任务已完成。例如:
gulp.task( "cb-task", function( done ){
fs.readFile( "filename", function( err, data ){
done();
});
});
通常情况下,您将返回类似示例1的流,这是典型的gulp任务的样子。选项2和3更适用于当您正在执行不是真正基于流的传统gulp任务时。
接下来要做的事情是为一个任务设置另一个任务的“依赖项”。Gulp文档将其显示为以下方式:
gulp.task( "some-task-with-deps", [ "array-of-dep", "task-names" ], function(){ });
现在我不知道当前的状态,但是这些依赖任务没有按照正确的顺序运行存在一些问题。这最初是由于 gulp 的一个依赖项(我相信是 orchestrator)出现了问题所致。在 NPM 领域中有一个好心人制作了一个很好的小包,在缺陷被修复期间使用它。我开始使用它来排序我的任务,从未回头过。
https://www.npmjs.com/package/run-sequence
文档很好,所以我在这里不会详细介绍。基本上,
run-sequence
允许您明确地排序gulp任务,只要记住,如果您没有为每个任务实现上述三个选项之一,则它将无法工作。
看看您的代码片段,在您的任务中添加几个缺失的返回语句可能就可以解决问题了,但是作为示例,这是我在工作项目中的“dev”任务的样子...
gulp.task( "dev", function( done ){
runSequence(
"build:dev",
"build:tests",
"server:dev",
[
"less:watch",
"jscs:watch",
"lint:watch",
"traceur:watch"
],
"jscs:dev",
"lint:dev",
"tdd",
done
);
});
此外,供参考,我的“build:dev”任务也使用了
run-sequence
。
gulp.task( "build:dev", function( done ){
runSequence(
"clean:dev",
[
"less:dev",
"symlink:dev",
"vendor:dev",
"traceur:dev"
],
done
);
});
如果需要按顺序运行任务,则将任务名称作为其自身参数添加到
runSequence
中。如果它们不冲突,则作为数组发送以使任务同时运行并加速构建过程。
关于监视任务,有一件事需要注意!通常,监视任务会无限期地运行,因此尝试从中返回“无限”流可能会使gulp认为该任务永远不会结束。在这种情况下,我将使用回调方法,即使任务仍在运行,也会让gulp认为任务已完成,类似于...
gulp.task( "watch-stuff", function( done ){
gulp.watch( watchGlob )
.on( "change", function( event ){ });
done();
});
关于观察任务和如何进行增量构建的更多信息,请查看我前几天写的一个答案,
增量 gulp less 构建。