如何运行Gulp任务顺序一个接一个

在这样的片段中:

gulp.task "coffee", ->
gulp.src("src/server/**/*.coffee")
.pipe(coffee {bare: true}).on("error",gutil.log)
.pipe(gulp.dest "bin")


gulp.task "clean",->
gulp.src("bin", {read:false})
.pipe clean
force:true


gulp.task 'develop',['clean','coffee'], ->
console.log "run something else"

develop任务中,我想运行clean,在它完成后,运行coffee,当它完成时,运行其他东西。但是我想不出来。这个零件坏了。请建议。

253116 次浏览

默认情况下,gulp同时运行任务,除非它们有显式的依赖关系。这对于像clean这样的任务不是很有用,在这些任务中,你不想依赖它们,但你需要在所有其他任务之前运行它们。

我专门写了run-sequence插件来用gulp解决这个问题。安装后,像这样使用它:

var runSequence = require('run-sequence');


gulp.task('develop', function(done) {
runSequence('clean', 'coffee', function() {
console.log('Run something else');
done();
});
});

您可以在README包上阅读完整的说明-它还支持同时运行一些任务集。

请注意,这将是(有效地)在gulp的下一个主要版本中修复,因为他们完全消除了自动依赖顺序,并提供类似run-sequence的工具,允许你手动指定运行顺序。

然而,这是一个重大的突破性变化,所以当你今天可以使用run-sequence时,没有理由等待。

这个问题的唯一好的解决方案可以在gulp文档中找到:

var gulp = require('gulp');


// takes in a callback so the engine knows when it'll be done
gulp.task('one', function(cb) {
// do stuff -- async or otherwise
cb(err); // if err is not null and not undefined, the orchestration will stop, and 'two' will not run
});


// identifies a dependent task must be complete before this one begins
gulp.task('two', ['one'], function() {
// task 'one' is done now
});


gulp.task('default', ['one', 'two']);
// alternatively: gulp.task('default', ['two']);

试试这个hack:-) 吞咽v3。x针对异步错误的Hack < / p > 我尝试了自述中所有的“官方”方法,它们对我不起作用,但这个对我有用。你也可以升级到gulp 4。x,但是我强烈建议你不要这样做,这样会弄坏很多东西。你可以使用一个真正的js承诺,但嘿,这是快速,肮脏,简单:-) 本质上你使用:

var wait = 0; // flag to signal thread that task is done
if(wait == 0) setTimeout(... // sleep and let nodejs schedule other threads

看看这个帖子!

我使用generator-gulp-webapp Yeoman生成器生成了一个node/gulp应用程序。它是这样处理“干净的难题”的(翻译成问题中提到的原始任务):

gulp.task('develop', ['clean'], function () {
gulp.start('coffee');
});

我也遇到过同样的问题,而且解决方法对我来说非常简单。基本上把你的代码改成下面的代码,它应该可以工作。注意:在吞咽前返回。SRC让我完全不同。

gulp.task "coffee", ->
return gulp.src("src/server/**/*.coffee")
.pipe(coffee {bare: true}).on("error",gutil.log)
.pipe(gulp.dest "bin")


gulp.task "clean",->
return gulp.src("bin", {read:false})
.pipe clean
force:true


gulp.task 'develop',['clean','coffee'], ->
console.log "run something else"

简单地让coffee依赖于clean,而develop依赖于coffee:

gulp.task('coffee', ['clean'], function(){...});
gulp.task('develop', ['coffee'], function(){...});

分派现在是串行的:cleancoffee & # 8594;develop。注意,clean的实现和coffee的实现必须接受一个回调,“这样引擎就知道什么时候能完工了”:

gulp.task('clean', function(callback){
del(['dist/*'], callback);
});

总之,下面是一个同步clean后面跟着异步构建依赖项的简单gulp模式:

//build sub-tasks
gulp.task('bar', ['clean'], function(){...});
gulp.task('foo', ['clean'], function(){...});
gulp.task('baz', ['clean'], function(){...});
...


//main build task
gulp.task('build', ['foo', 'baz', 'bar', ...], function(){...})

Gulp足够聪明,可以对每个build运行clean一次,不管build有多少依赖于clean。如上所述,clean是一个同步障碍,然后所有build的依赖项并行运行,然后build运行。

它还没有正式发布,但是即将发布的Gulp 4.0让您可以轻松地使用Gulp .series完成同步任务。你可以简单地这样做:

gulp.task('develop', gulp.series('clean', 'coffee'))
我发现了一篇很好的博客文章,介绍了如何升级和使用这些整洁的功能: 通过示例迁移到gulp 4 < / p >

根据Gulp的文档:

您的任务是否在依赖项完成之前运行?确保你的依赖任务正确使用异步运行提示:接受回调或返回承诺或事件流。

同步运行你的任务序列:

  1. 返回事件流(例如gulp.src)给gulp.task通知 流何时结束的任务
  2. gulp.task的第二个参数中声明任务依赖项。

参见修订后的代码:

gulp.task "coffee", ->
return gulp.src("src/server/**/*.coffee")
.pipe(coffee {bare: true}).on("error",gutil.log)
.pipe(gulp.dest "bin")


gulp.task "clean", ['coffee'], ->
return gulp.src("bin", {read:false})
.pipe clean
force:true


gulp.task 'develop',['clean','coffee'], ->
console.log "run something else"

我一直在寻找这个答案。现在我在gulp的官方文档里找到了。

如果你想在最后一个任务完成时执行gulp任务,你必须返回一个流:

.
gulp.task('wiredep', ['dev-jade'], function () {
var stream = gulp.src(paths.output + '*.html')
.pipe($.wiredep())
.pipe(gulp.dest(paths.output));


return stream; // execute next task when this is completed
});


// First will execute and complete wiredep task
gulp.task('prod-jade', ['wiredep'], function() {
gulp.src(paths.output + '**/*.html')
.pipe($.minifyHtml())
.pipe(gulp.dest(paths.output));
});

Gulp和Node使用承诺

所以你可以这样做:

// ... require gulp, del, etc


function cleanTask() {
return del('./dist/');
}


function bundleVendorsTask() {
return gulp.src([...])
.pipe(...)
.pipe(gulp.dest('...'));
}


function bundleAppTask() {
return gulp.src([...])
.pipe(...)
.pipe(gulp.dest('...'));
}


function tarTask() {
return gulp.src([...])
.pipe(...)
.pipe(gulp.dest('...'));
}


gulp.task('deploy', function deployTask() {
// 1. Run the clean task
cleanTask().then(function () {
// 2. Clean is complete. Now run two tasks in parallel
Promise.all([
bundleVendorsTask(),
bundleAppTask()
]).then(function () {
// 3. Two tasks are complete, now run the final task.
tarTask();
});
});
});

如果返回gulp流,则可以使用then()方法添加回调。另外,你也可以使用Node的原生Promise来创建你自己的promise。在这里,我使用Promise.all()有一个回调,当所有承诺解决时触发。

对我来说,它不是在连接后运行minify任务,因为它期望连接的输入,而且它没有生成一些时间。

我尝试按执行顺序添加到默认任务,但没有工作。它在为每个任务添加return并在gulp.start()中进行缩小后工作,如下所示。

/**
* Concatenate JavaScripts
*/
gulp.task('concat-js', function(){
return gulp.src([
'js/jquery.js',
'js/jquery-ui.js',
'js/bootstrap.js',
'js/jquery.onepage-scroll.js',
'js/script.js'])
.pipe(maps.init())
.pipe(concat('ux.js'))
.pipe(maps.write('./'))
.pipe(gulp.dest('dist/js'));
});


/**
* Minify JavaScript
*/
gulp.task('minify-js', function(){
return gulp.src('dist/js/ux.js')
.pipe(uglify())
.pipe(rename('ux.min.js'))
.pipe(gulp.dest('dist/js'));
});


gulp.task('concat', ['concat-js'], function(){
gulp.start('minify-js');
});


gulp.task('default',['concat']);

http://schickling.me/synchronous-tasks-gulp/

运行序列是最明确的方法(至少在Gulp 4.0发布之前)

与运行序列,你的任务看起来像这样:

var sequence = require('run-sequence');
/* ... */
gulp.task('develop', function (done) {
sequence('clean', 'coffee', done);
});

但如果你(出于某种原因)不喜欢使用它,gulp.start方法将有所帮助:

gulp.task('develop', ['clean'], function (done) {
gulp.on('task_stop', function (event) {
if (event.task === 'coffee') {
done();
}
});
gulp.start('coffee');
});

注意: 如果你只启动任务而不听结果,__ABC0任务将比coffee更早完成,这可能会令人困惑。

你也可以在不需要的时候删除事件监听器

gulp.task('develop', ['clean'], function (done) {
function onFinish(event) {
if (event.task === 'coffee') {
gulp.removeListener('task_stop', onFinish);
done();
}
}
gulp.on('task_stop', onFinish);
gulp.start('coffee');
});

考虑你可能想听的还有task_err事件task_stop在成功完成时被触发,而当出现一些错误时出现task_err

你可能也想知道为什么没有gulp.start()的官方文档。来自gulp成员的回答解释了这些事情:

gulp.start是故意没有记录的,因为它会导致复杂的构建文件,我们不希望人们使用它

(来源:https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007)

尝试了所有提出的解决方案,似乎都有自己的问题。

如果你真正查看Orchestrator源代码,特别是.start()实现,你会发现如果最后一个参数是一个函数,它会将其视为一个回调。

我为自己的任务写了这个片段:

  gulp.task( 'task1', () => console.log(a) )
gulp.task( 'task2', () => console.log(a) )
gulp.task( 'task3', () => console.log(a) )
gulp.task( 'task4', () => console.log(a) )
gulp.task( 'task5', () => console.log(a) )


function runSequential( tasks ) {
if( !tasks || tasks.length <= 0 ) return;


const task = tasks[0];
gulp.start( task, () => {
console.log( `${task} finished` );
runSequential( tasks.slice(1) );
} );
}
gulp.task( "run-all", () => runSequential([ "task1", "task2", "task3", "task4", "task5" ));

等着看任务是否完成,然后剩下的,我是这样做的:

gulp.task('default',
gulp.series('set_env', gulp.parallel('build_scss', 'minify_js', 'minify_ts', 'minify_html', 'browser_sync_func', 'watch'),
function () {
}));

荣誉:https://fettblog.eu/gulp-4-parallel-and-series/

我发现一个接一个执行任务的非常简单和有效的解决方案(当一个任务完成时,第二个任务将被启动)(仅提供一个例子)是 gulp.task('watch', () => < br > gulp.watch(['src/**/*.css', 'src/**/*.pcss'], gulp.series('build',['copy'])) ); < br > 这意味着当你需要在second-task之前运行first-task时,你需要用方括号写第二个任务(在本例中是copy)。 < br > < br >注意 任务的外部应该有圆括号(除非您希望它们同时发生)