Jak uruchamiać zadania Gulp kolejno jeden po drugim

W takim fragmencie:

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"

W develop zadanie chcę uruchomić clean i po jego zakończeniu, uruchomić coffee i kiedy to się skończy, uruchomić coś innego. Ale nie mogę tego rozgryźć. Ten kawałek nie działa. Proszę o radę.

Author: Jacob, 2014-04-03

13 answers

Nie jest to jeszcze oficjalne wydanie, ale nadchodzi Gulp 4.0 pozwala łatwo wykonywać zadania synchroniczne z gulp.seria. Możesz to po prostu zrobić tak:

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

Znalazłem dobry wpis na blogu przedstawiający jak uaktualnić i wykorzystać te fajne funkcje: migracja do gulp 4 Przez przykład

 91
Author: massanishi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-06 16:08:28

Domyślnie gulp uruchamia zadania jednocześnie, chyba że mają wyraźne zależności. Nie jest to zbyt przydatne do zadań takich jak clean, gdzie nie chcesz polegać, ale musisz je uruchomić przed wszystkim innym.

Napisałem run-sequence plugin specjalnie, aby rozwiązać ten problem z gulp. Po zainstalowaniu użyj go w ten sposób:

var runSequence = require('run-sequence');

gulp.task('develop', function(done) {
    runSequence('clean', 'coffee', function() {
        console.log('Run something else');
        done();
    });
});

Możesz przeczytać pełną instrukcję na pakiecie README-obsługuje on również uruchamianie niektórych zestawów zadań jednocześnie.

Proszę zauważyć, że zostanie to (efektywnie) naprawione w następnym głównym wydaniu gulp , ponieważ całkowicie eliminuje automatyczne porządkowanie zależności i dostarcza narzędzia podobne do run-sequence, które pozwalają ręcznie określić kolejność uruchamiania, jak chcesz.

Jest to jednak duża przełomowa zmiana, więc nie ma powodu, aby czekać, kiedy można użyć run-sequence dzisiaj.

 399
Author: OverZealous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-05 23:57:20

Jedyne dobre rozwiązanie tego problemu można znaleźć w dokumentacji gulp, którą można znaleźć Tutaj

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']);
 362
Author: Mathieu Borderé,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-09 12:36:59

Wygenerowałem aplikację node/gulp używając generatora-gulp-webapp Yeoman generator. W ten sposób rozwiązał "czystą zagadkę" (tłumacząc na oryginalne zadania wymienione w pytaniu):

gulp.task('develop', ['clean'], function () {
  gulp.start('coffee');
});
 51
Author: Steve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-19 20:31:41

Run-sequence jest najbardziej przejrzystym sposobem (przynajmniej do czasu wydania Gulp 4.0)

W przypadku run-sequence Twoje zadanie będzie wyglądało tak:

var sequence = require('run-sequence');
/* ... */
gulp.task('develop', function (done) {
    sequence('clean', 'coffee', done);
});

Ale jeśli (z jakiegoś powodu) wolisz go nie używać, gulp.start metoda pomoże :

gulp.task('develop', ['clean'], function (done) {
    gulp.on('task_stop', function (event) {
        if (event.task === 'coffee') {
            done();
        }
    });
    gulp.start('coffee');
});

Uwaga: jeśli rozpoczniesz zadanie bez słuchania wyniku, develop zakończy się wcześniej niż coffee, co może być mylące.

Możesz również usunąć zdarzenie słuchacz gdy nie jest potrzebny

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');
});

Rozważ istnieje również task_err wydarzenie , którego możesz chcieć posłuchać. task_stop jest uruchamiany po pomyślnym zakończeniu, podczas gdy task_err pojawia się, gdy wystąpi jakiś błąd.

Możesz się również zastanawiać, dlaczego nie ma oficjalnej dokumentacji gulp.start(). Ta odpowiedź od członka gulp wyjaśnia rzeczy:

gulp.start jest celowo nieudokumentowana, ponieważ może prowadzić do skomplikowanych plików kompilacji i nie chcemy, aby ludzie używali it

(źródło: https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007 )

 30
Author: thybzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-07 21:18:26

Według dokumentów Gulp:

Czy Twoje zadania są uruchamiane przed ukończeniem zależności? Upewnij się, że zadania zależności są prawidłowo za pomocą asynchronicznych podpowiedzi: weź w callback lub zwrócić obietnicę lub strumień zdarzeń.

Aby uruchomić sekwencję zadań synchronicznie:

  1. zwraca strumień zdarzeń (np. gulp.src) do gulp.task, aby poinformować zadanie kiedy strumień się kończy.
  2. deklaruje zależności zadań w drugim argumencie gulp.task.

Zobacz poprawiony kod:

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"
 25
Author: senornestor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-24 18:11:16

Miałem dokładnie ten sam problem i rozwiązanie okazało się dla mnie dość łatwe. Zasadniczo Zmień kod na następujący i powinno działać. Uwaga: powrót przed łyknięciem.src zrobiło dla mnie różnicę.

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
Author: Craig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-24 11:21:15

Próbowałem wszystkich proponowanych rozwiązań, wszystkie wydają się mieć własne problemy.

Jeśli przyjrzysz się źródłu Orchestratora, szczególnie implementacji .start() zobaczysz, że jeśli ostatni parametr jest funkcją, będzie traktował ją jako wywołanie zwrotne.

Napisałem ten fragment do własnych zadań:

  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" ));
 5
Author: Assaf Moldavsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-24 22:18:10

Szukałem tej odpowiedzi przez jakiś czas. Teraz mam to w oficjalnej dokumentacji gulp.

Jeśli chcesz wykonać zadanie gulp po zakończeniu ostatniego, musisz zwrócić strumień:

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
Author: Lucho Suárez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 09:48:28

Dla mnie nie uruchamiało zadania minify po konkatenacji, ponieważ oczekuje konkatenowanych danych wejściowych i nie było generowane kilka razy.

Próbowałem dodać do domyślnego zadania w kolejności wykonania i nie zadziałało. Zadziałało po dodaniu tylko return dla każdego zadania i uzyskaniu minifikacji wewnątrz gulp.start() Jak Poniżej.

/**
* 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']); 

Źródło http://schickling.me/synchronous-tasks-gulp/

 3
Author: devo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-21 08:30:04

Po prostu make coffee depend on clean, and develop depend on coffee:

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

Dyspozytor jest teraz seryjny: cleancoffeedevelop. Zauważ, że implementacja clean i implementacja coffee muszą zaakceptować wywołanie zwrotne, "aby silnik wiedział, kiedy to się skończy":

gulp.task('clean', function(callback){
  del(['dist/*'], callback);
});
Na zakończenie, poniżej znajduje się prosty wzorzec gulp dla synchronicznego clean, po którym następują asynchroniczne zależności budowania :
//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 jest wystarczająco mądry, aby uruchomić clean dokładnie raz na build, bez względu na to, ile z build zależą od clean. Jak napisano powyżej, clean jest barierą synchronizacji, wtedy wszystkie zależności build działają równolegle, a następnie build działają.

 2
Author: akarve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-04 23:52:24

Gulp i node use obiecuje .

Więc możesz to zrobić:

// ... 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();
    });
  });
});

Jeśli zwrócisz strumień gulp, możesz użyć metody then(), aby dodać wywołanie zwrotne. Alternatywnie, możesz użyć natywnego Promise Node do tworzenia własnych obietnic. Tutaj używam Promise.all(), aby mieć jedno wywołanie zwrotne, które zostanie wywołane, gdy wszystkie obietnice zostaną rozwiązane.

 2
Author: Peter J. Hart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 17:34:00

Try this hack :-) Gulp v3.X Hack For async bug

Próbowałem wszystkich "oficjalnych" sposobów w Readme, nie działały dla mnie, ale to tak. Można również uaktualnić do gulp 4.x ale Gorąco polecam nie, psuje tyle rzeczy. Przydałaby ci się prawdziwa obietnica js, ale hej, to jest szybkie, brudne, proste :-) Zasadniczo używasz:

var wait = 0; // flag to signal thread that task is done
if(wait == 0) setTimeout(... // sleep and let nodejs schedule other threads

Zobacz post!

 -7
Author: Will Bittner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-17 03:32:03