Как последовательно запускать задачи 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
, и когда это будет сделано, запустите что-то еще. Но я не могу понять это. Эта часть не работает. Пожалуйста, порекомендуйте.
Ответы
Ответ 1
Это еще не официальный релиз, приходящий Gulp 4.0 позволяет легко выполнять синхронные задачи с gulp.series. Вы можете просто сделать это следующим образом:
gulp.task('develop', gulp.series('clean', 'coffee'))
Я нашел хорошее сообщение в блоге о том, как обновить и использовать эти аккуратные функции:
переход на Gulp 4 на примере
Ответ 2
По умолчанию 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
сегодня.
Ответ 3
Единственное хорошее решение этой проблемы можно найти в документации 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']);
Ответ 4
Я сгенерировал приложение node/gulp, используя generator-gulp-webapp Генератор Yeoman. Он обрабатывал "чистую головоломку" таким образом (перевод на оригинальные задачи, упомянутые в вопросе):
gulp.task('develop', ['clean'], function () {
gulp.start('coffee');
});
Ответ 5
В соответствии с Gulp документами:
Выполняются ли ваши задачи до завершения зависимостей? Убедитесь, что ваши задачи зависимостей правильно используются подсказками async run: выполните обратный вызов или верните обещание или поток событий.
Синхронизировать последовательность задач:
- Верните поток событий (например,
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"
Ответ 6
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)
Ответ 7
У меня была такая же проблема, и решение оказалось для меня довольно легким. В основном измените свой код на следующий, и он должен работать. ПРИМЕЧАНИЕ: возврат до 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"
Ответ 8
Я искал этот ответ некоторое время. Теперь я получил его в официальной документации 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));
});
Ответ 9
Для меня он не запускал задачу 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/
Ответ 10
попробовали все предлагаемые решения, все, похоже, имеют свои проблемы.
Если вы действительно посмотрите на источник 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" ));
Ответ 11
Просто заставьте coffee
зависеть от clean
, а develop
зависит от coffee
:
gulp.task('coffee', ['clean'], function(){...});
gulp.task('develop', ['coffee'], function(){...});
Отправка теперь последовательна: clean
→ coffee
→ develop
. Обратите внимание, что реализация clean
и coffee
реализация должны принимать обратный вызов ", поэтому движок знает, когда это будет сделано" :
gulp.task('clean', function(callback){
del(['dist/*'], callback);
});
В заключение ниже приведен шаблон простой gulp для синхронного 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 достаточно умен, чтобы запустить clean
ровно один раз за build
, независимо от того, сколько зависимостей build
зависит от clean
. Как указано выше, clean
является барьером синхронизации, тогда все зависимости build
выполняются параллельно, затем выполняется build
.
Ответ 12
Gulp и Node используйте promises.
Итак, вы можете сделать это:
// ... 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 native Promise
, чтобы создать свой собственный promises. Здесь я использую Promise.all()
, чтобы иметь один обратный вызов, который срабатывает, когда разрешается все promises.
Ответ 13
Попробуй этот хак:-)
Gulp v3.x Hack для ошибки Async
Я пробовал все "официальные" способы в Readme, они не работали для меня, но это было сделано. Вы также можете перейти на 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
Отправляй сообщение!