web-dev-qa-db-ja.com

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を実行し、それが終わったら他のものを実行してください。しかし、私はそれを理解することはできません。この作品はうまくいきません。お知らせ下さい。

385
iLemming

まだ正式なリリースではありませんが、近々登場するGulp 4.0では、gulp.seriesを使って簡単に同期タスクを実行できます。あなたは単純にこれのようにそれをすることができます:

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

私はこれらの素晴らしい機能をアップグレードして利用する方法を紹介する良いブログ記事を見つけました: 例によるgulp 4への移行

108
massanishi

デフォルトでは、明示的な依存関係がない限り、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 - に関する完全な説明を読むことができます - それはまた、同時にタスクのいくつかのセットを実行することをサポートします。

自動依存関係の順序付けを完全に排除し、手動で実行順序を手動で指定できるようにするためのrun-sequenceのようなツールを提供するので、これは gulpの次のメジャーリリースで修正される になります。欲しいです。

しかし、これは大きな変更点なので、今日run-sequenceを使用できるようになるのを待つ理由はありません。

406
OverZealous

この問題に対する唯一の良い解決策はgulpのドキュメントにあります。{ here

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

generator-gulp-webapp Yeomanジェネレータを使ってnode/gulpアプリを生成しました。それは「きれいな難問」をこのように扱った(質問で述べられた元のタスクに翻訳する):

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

run-sequence は(少なくともGulp 4.0がリリースされるまでは)最も明確な方法です。

run-sequence では、タスクは次のようになります。

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.startは意図的に文書化されていません。ビルドファイルが複雑になる可能性があるためです。

(出典: https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007

31
thybzi

Gulpの文書によると:

依存関係が完了する前にタスクが実行されていますか?依存関係のタスクが非同期実行のヒントを正しく使用していることを確認してください。コールバックを受け取るか、promiseまたはeventストリームを返します。

一連のタスクを同期的に実行するには

  1. イベントストリーム(例:gulp.src)をgulp.taskに返して、ストリームがいつ終了するかをタスクに通知します。
  2. gulp.taskの2番目の引数でタスクの依存関係を宣言します。

改訂コードを参照してください。

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"
26
senornestor

私はこれとまったく同じ問題を抱えていましたが、解決策は私にとってはかなり簡単であることがわかりました。基本的にあなたのコードを以下のように変更すればうまくいくでしょう。注: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"
9
Craig

提案されたすべての解決策を試してみましたが、すべて独自の問題を抱えているようです。

実際に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" ));
7
Assaf Moldavsky

私にとっては、連結入力を想定していて、生成されなかったため、連結後に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/ /

3
devo

単にcoffeecleanに依存させ、developcoffeeに依存させるだけです:

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

ディスパッチはシリアルになりました:cleancoffeedevelopcleanの実装とcoffeeの実装mustはコールバックを受け入れることに注意してください "したがって、エンジンは終了します」

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

結論として、以下は同期cleansimple 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は、cleanの依存関係の数がbuildに依存している場合でも、buildごとに1回だけcleanを実行できるほどスマートです。上記のように、cleanは同期バリアであり、buildのすべての依存関係が並行して実行され、その後buildが実行されます。

3
akarve

私はしばらくこの答えを探していました。今、私は公式の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));
});
3
Lucho Suárez

GulpとNodeは promise を使います。

だからあなたはこれを行うことができます:

// ... 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()を使って、すべての約束が解決したときに起動する1つのコールバックを持っています。

2
Peter J. Hart