このようなスニペットでは:
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'))
私はこれらの素晴らしい機能をアップグレードして利用する方法を紹介する良いブログ記事を見つけました: 例によるgulp 4への移行
デフォルトでは、明示的な依存関係がない限り、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
を使用できるようになるのを待つ理由はありません。
この問題に対する唯一の良い解決策は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']);
generator-gulp-webapp Yeomanジェネレータを使ってnode/gulpアプリを生成しました。それは「きれいな難問」をこのように扱った(質問で述べられた元のタスクに翻訳する):
gulp.task('develop', ['clean'], function () {
gulp.start('coffee');
});
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 )
Gulpの文書によると:
依存関係が完了する前にタスクが実行されていますか?依存関係のタスクが非同期実行のヒントを正しく使用していることを確認してください。コールバックを受け取るか、promiseまたはeventストリームを返します。
一連のタスクを同期的に実行するには
gulp.src
)をgulp.task
に返して、ストリームがいつ終了するかをタスクに通知します。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"
私はこれとまったく同じ問題を抱えていましたが、解決策は私にとってはかなり簡単であることがわかりました。基本的にあなたのコードを以下のように変更すればうまくいくでしょう。注: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"
提案されたすべての解決策を試してみましたが、すべて独自の問題を抱えているようです。
実際に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" ));
私にとっては、連結入力を想定していて、生成されなかったため、連結後に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']);
単にcoffee
をclean
に依存させ、develop
をcoffee
に依存させるだけです:
gulp.task('coffee', ['clean'], function(){...});
gulp.task('develop', ['coffee'], function(){...});
ディスパッチはシリアルになりました:clean
→coffee
→develop
。 clean
の実装とcoffee
の実装mustはコールバックを受け入れることに注意してください "したがって、エンジンは終了します」 :
gulp.task('clean', function(callback){
del(['dist/*'], callback);
});
結論として、以下は同期clean
のsimple 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
が実行されます。
私はしばらくこの答えを探していました。今、私は公式の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は 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つのコールバックを持っています。