Как запускать задачи 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 и когда это будет сделано, запустите что-нибудь еще. Но я не могу этого понять. Эта штука не работает. Посоветуйте, пожалуйста.

711   13  

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:

выполняются ли ваши задачи до завершения зависимостей? Убедитесь, что ваши задачи зависимостей правильно используют подсказки асинхронного запуска: возьмите обратный вызов или верните обещание или поток событий.

для синхронного выполнения последовательности задач:

  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"

У меня была точно такая же проблема и решение оказалось довольно простым для меня. В принципе изменить код на следующий и он должен работать. Примечание: возвращение перед глотком.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']); 

Источник http://schickling.me/synchronous-tasks-gulp/

просто coffee зависит от clean и develop зависит от coffee:

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

отправка теперь серийный: cleancoffeedevelop. Обратите внимание, что и С должны принять звонок, "чтобы двигатель знал, когда это будет сделано":

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

    Ничего не найдено.