it-swarm.com.ru

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

389
iLemming

Это еще не официальный релиз, но выход Gulp 4.0 позволяет легко выполнять синхронные задачи с gulp.series. Вы можете просто сделать это так:

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

Я нашел хороший пост в блоге, в котором рассказывается, как обновить и использовать эти полезные функции: переход на gulp 4 в качестве примера

111
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 - он также поддерживает одновременное выполнение некоторых наборов задач.

Обратите внимание, что это будет (эффективно) исправлено в следующей основной версии gulp , поскольку они полностью устраняют автоматическое упорядочение зависимостей и предоставляют инструменты, подобные run-sequence, чтобы позволить вам вручную указать порядок выполнения как ты хочешь.

Однако это серьезное изменение, поэтому нет причин ждать, когда вы сможете использовать run-sequence сегодня.

408
OverZealous

Единственное хорошее решение этой проблемы можно найти в документации 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']);
370
Mathieu Borderé

Я сгенерировал приложение node/gulp, используя генератор generator-gulp-webapp Yeoman. Он решал "чистую головоломку" таким образом (переводя к оригинальным задачам, упомянутым в вопросе):

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

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.start специально не задокументирован, потому что это может привести к сложным файлам сборки, и мы не хотим, чтобы люди его использовали

(источник: https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007 )

31
thybzi

Согласно документации 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"
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

Просто установите coffee в зависимости от clean, а develop в зависимости от coffee:

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

Отправка теперь последовательная: cleancoffeedevelop. Обратите внимание, что реализация 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.

3
akarve

Я долго искал этот ответ. Теперь я получил это в официальной документации глотка.

Если вы хотите выполнить задачу 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 используют обещания.

Так что вы можете сделать это:

// ... 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() для добавления обратного вызова. Кроме того, вы можете использовать нативное Promise для Node, чтобы создавать свои собственные обещания. Здесь я использую Promise.all(), чтобы иметь один обратный вызов, который срабатывает, когда все обещания разрешаются.

2
Peter J. Hart