Как запускать задачи 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 и когда это будет сделано, запустите что-нибудь еще. Но я не могу этого понять. Эта штука не работает. Посоветуйте, пожалуйста.
13 ответов:
это еще не официальный релиз, но предстоящий Gulp 4.0 позволяет легко выполнять синхронные задачи с gulp.серии. Вы можете просто сделать это так:
gulp.task('develop', gulp.series('clean', 'coffee'))Я нашел хороший пост в блоге, представляющий, как обновить и использовать эти аккуратные функции: переход к gulp 4 на примере
по умолчанию gulp выполняет задачи одновременно, если они не имеют явных зависимостей. Это не очень полезно для таких задач, как
clean, где вы не хотите зависеть, но вам нужно, чтобы они работали прежде всего.я писал the
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']);
Я создал приложение node / gulp с помощью генератор-глоток-webapp генератор Yeoman. Он обработал "чистую головоломку" таким образом (перевод на исходные задачи, упомянутые в вопросе):
gulp.task('develop', ['clean'], function () { gulp.start('coffee'); });
run-sequence это самый понятный способ (по крайней мере, пока 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.start- это недокументированный специально, потому что это может привести к сложным файлам сборки, и мы не хотим, чтобы люди использовали его(источник:https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007)
согласно документам Gulp:
выполняются ли ваши задачи до завершения зависимостей? Убедитесь, что ваши задачи зависимостей правильно используют подсказки асинхронного запуска: возьмите обратный вызов или верните обещание или поток событий.
для синхронного выполнения последовательности задач:
- возврат потока событий (например
gulp.src) вgulp.taskсообщить задача о том, когда поток заканчивается.- объявить зависимости задач в второй аргумент
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"
У меня была точно такая же проблема и решение оказалось довольно простым для меня. В принципе изменить код на следующий и он должен работать. Примечание: возвращение перед глотком.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" ));
Я искал этот ответ на некоторое время. Теперь я получил его в официальной документации глотка.
Если вы хотите выполнить задачу 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)); });
для меня он не запускал задачу 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. Обратите внимание, что и С должны принять звонок, "чтобы двигатель знал, когда это будет сделано":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(){...})глоток достаточно умен, чтобы бежать
cleanровно один раз вbuild, независимо от того, сколько наclean. Как написано выше,cleanявляется барьером синхронизации, то всеbuildзависимости выполняются параллельно, затемbuildработает.
глоток и использование узла обещания.
так что вы можете сделать это:
// ... 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(); }); }); });если вы возвращаете поток глотка, вы можете использовать
then()метод для добавления обратного вызова. Кроме того, вы можете использовать родной узелPromiseсоздать свои собственные обещания. Здесь я используюPromise.all()чтобы иметь один обратный вызов, который срабатывает, когда все обещания разрешаются.
попробуйте этот хак :-) глоток v3.X Hack для асинхронной ошибки
Я пробовал все "официальные" способы в Readme, они не работали для меня, но это так. Вы также можете перейти на gulp 4.но я настоятельно рекомендую вам этого не делать, это ломает так много вещей. Вы могли бы использовать настоящее обещание js, но эй, это быстро, грязно, просто :-) По существу вы используете:
var wait = 0; // flag to signal thread that task is done if(wait == 0) setTimeout(... // sleep and let nodejs schedule other threadsпроверить пост!
Comments