如何依次运行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 ,当完成后,运行其他的东西。 但我无法弄清楚。 这件作品不起作用。 请指教。

现在还没有正式发布,即将推出的Gulp 4.0可以让你轻松完成与gulp.series的同步任务。 你可以简单地这样做:

 gulp.task('develop', gulp.series('clean', 'coffee')) 

我找到了一篇很好的博客文章,介绍如何升级和使用这些整齐的功能: 通过示例迁移到吞噬4

默认情况下,gulp同时运行任务,除非它们有明确的依赖关系。 这对于clean任务来说并不是非常有用,你不需要依赖它,但是你需要它们在一切之前运行。

我特意写了run-sequence插件来解决这个问题。 安装完成后,请像这样使用它:

 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']); 

我使用generator-gulp-webapp Yeoman生成器生成了一个节点/ gulp应用程序。 它以这种方式处理了“干净的难题”(转化为问题中提到的原始任务):

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

根据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 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'); }); 

注意: 如果您只是在不听结果的情况下启动任务,那么develop任务将比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.startgulp.start的,因为它可能会导致复杂的构建文件,我们不希望人们使用它

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

我有这个完全相同的问题,解决方案对我来说很容易。 基本上改变你的代码以下,它应该工作。 注意:gulp.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" 

我正在寻找这个答案一段时间。 现在我在官方文档中找到了它。

如果您想在最后一个完成时执行吞吐任务,则必须返回一个流:

 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)); }); 

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

我尝试添加到执行顺序的默认任务,它没有奏效。 它添加了每个任务的return ,并在下面的gulp.start()得到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/

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

如果你真的关注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" )); 

简单地使coffee依靠clean ,并依靠coffee develop

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

调度现在是连续的: cleancoffeedevelop 。 请注意, clean的实现和coffee的实现必须接受回调, “所以引擎知道什么时候会完成” :

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

总之,下面是一个简单的吞咽模式,用于同步clean然后是异步构建依赖关系

 //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只需运行一次,无论build的依赖项有多少取决于clean 。 如上所述, clean是一个同步障碍,然后所有的build依赖运行并行,然后build运行。

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.all()有一个回调,当所有的承诺解决时触发。

尝试这个黑客:-) Gulp v3.x黑客异步错误

我在自述文件中尝试了所有“官方”方式,但它们并不适用于我,但是这样做。 你也可以升级到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 

看看帖子!

Interesting Posts