wake-up-neo.com

So führen Sie Gulp-Tasks nacheinander aus

im Snippet wie folgt:

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"

In der develop Aufgabe möchte ich clean ausführen und nachdem dies erledigt ist, führe coffee aus und wenn dies erledigt ist, führe etwas anderes aus. Aber das kann ich nicht herausfinden. Dieses Stück funktioniert nicht. Bitte beraten.

393
iLemming

Es ist noch keine offizielle Version, aber mit Gulp 4.0 können Sie problemlos synchrone Aufgaben mit gulp.series ausführen. Sie können es einfach so machen:

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

Ich habe einen guten Blog-Beitrag gefunden, in dem beschrieben wird, wie man ein Upgrade durchführt und die netten Funktionen nutzt: Migration auf gulp 4 durch Beispiel

116
massanishi

Standardmäßig führt gulp Tasks gleichzeitig aus, sofern sie keine expliziten Abhängigkeiten aufweisen. Dies ist nicht sehr nützlich für Aufgaben wie clean, bei denen Sie nicht abhängig sein möchten, diese aber vor allen anderen Aufgaben ausführen müssen.

Ich habe das run-sequence Plugin geschrieben, um dieses Problem mit gulp zu beheben. Nachdem Sie es installiert haben, verwenden Sie es wie folgt:

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

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

Sie können die vollständigen Anweisungen auf dem Paket README lesen - es unterstützt auch das gleichzeitige Ausführen einiger Aufgabensätze.

Bitte beachten Sie, dass dies (effektiv) in der nächsten Hauptversion von gulp behoben wird , da die automatische Abhängigkeitsreihenfolge vollständig beseitigt wird und Tools bereitgestellt werden, die run-sequence ähneln, damit Sie manuell vorgehen können Geben Sie die gewünschte Ausführungsreihenfolge an.

Dies ist jedoch eine wichtige Änderung, sodass es keinen Grund gibt zu warten, wann Sie run-sequence heute verwenden können.

410
OverZealous

Die einzig gute Lösung für dieses Problem finden Sie in der Gulp-Dokumentation hier

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

Ich habe mit der generator-gulp-webapp Yeoman-Generator eine Node/gulp-App generiert. Es handhabte das "saubere Rätsel" auf diese Weise (übersetzt in die ursprünglichen Aufgaben, die in der Frage erwähnt wurden):

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

Laufsequenz ist der klarste Weg (zumindest bis Gulp 4.0 veröffentlicht wird)

Mit run-sequence sieht Ihre Aufgabe folgendermaßen aus:

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

Aber wenn Sie es (aus irgendeinem Grund) nicht verwenden möchten, hilft die Methode gulp.start:

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

Hinweis: Wenn Sie die Aufgabe nur starten, ohne das Ergebnis abzuhören, wird die Aufgabe develop vor coffee beendet. Dies kann verwirrend sein .

Sie können den Ereignis-Listener auch entfernen , wenn er nicht benötigt wird

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

Bedenken Sie , dass es auch ein _task_err_ -Ereignis gibt , das Sie sich anhören möchten. _task_stop_ wird bei erfolgreichem Abschluss ausgelöst, während _task_err_ angezeigt wird, wenn ein Fehler vorliegt.

Sie fragen sich vielleicht auch, warum es für gulp.start() keine offizielle Dokumentation gibt. Diese Antwort von gulp member erklärt die Dinge:

_gulp.start_ ist absichtlich nicht dokumentiert, da dies zu komplizierten Build-Dateien führen kann und wir nicht möchten, dass Benutzer sie verwenden

(Quelle: https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007 )

32
thybzi

Nach den Gulp-Dokumenten:

Werden Ihre Aufgaben ausgeführt, bevor die Abhängigkeiten abgeschlossen sind? Stellen Sie sicher, dass Ihre Abhängigkeitstasks die asynchronen Ausführungshinweise korrekt verwenden: Nehmen Sie einen Rückruf entgegen oder geben Sie eine Zusage oder einen Ereignisstrom zurück.

So führen Sie Ihre Tasksequenz synchron aus:

  1. Geben Sie den Ereignisstrom (z. B. gulp.src) an gulp.task zurück, um die Task darüber zu informieren, wann der Strom endet.
  2. Deklarieren Sie Aufgabenabhängigkeiten im zweiten Argument von gulp.task.

Siehe den überarbeiteten Code:

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

Ich hatte genau das gleiche Problem und die Lösung erwies sich als ziemlich einfach für mich. Grundsätzlich ändern Sie Ihren Code wie folgt und es sollte funktionieren. HINWEIS: Die Rückkehr vor gulp.src hat für mich den Unterschied ausgemacht.

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

alle Lösungsvorschläge ausprobiert, alle scheinen eigene Probleme zu haben.

Wenn Sie sich die Orchestrator-Quelle genauer ansehen, insbesondere die Implementierung von .start(), werden Sie feststellen, dass der letzte Parameter eine Funktion ist, die ihn als Rückruf behandelt.

Ich habe dieses Snippet für meine eigenen Aufgaben geschrieben:

  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

Ich habe eine Weile nach dieser Antwort gesucht. Jetzt habe ich es in der offiziellen Schluckdokumentation.

Wenn Sie eine Schluckaufgabe ausführen möchten, wenn die letzte abgeschlossen ist, müssen Sie einen Stream zurückgeben:

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));
});
4
Lucho Suárez

Bei mir wurde der Minify-Task nach der Verkettung nicht ausgeführt, da er verkettete Eingaben erwartet und einige Male nicht generiert wurde.

Ich habe versucht, eine Standardaufgabe in der Ausführungsreihenfolge hinzuzufügen, aber es hat nicht funktioniert. Es hat funktioniert, nachdem für jede Aufgabe nur ein return hinzugefügt wurde und die Verkleinerung in gulp.start() (siehe unten) erfolgt ist.

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

Quelle http://schickling.me/synchronous-tasks-gulp/

3
devo

Stellen Sie einfach coffee von clean und develop von coffee abhängig:

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

Der Versand erfolgt jetzt seriell: cleancoffeedevelop. Beachten Sie, dass die Implementierung von clean und die Implementierung von coffee einen Rückruf akzeptieren müssen , ", damit die Engine weiß, wann es wird gemacht " :

gulp.task('clean', function(callback){
  del(['dist/*'], callback);
});

Abschließend folgt ein einfaches Schluckmuster für ein synchrones clean gefolgt von asynchronen Build-Abhängigkeiten :

//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 ist intelligent genug, um clean genau einmal pro build auszuführen, unabhängig davon, wie viele Abhängigkeiten build von clean abhängen. Wie oben geschrieben, ist clean eine Synchronisationssperre, dann laufen alle Abhängigkeiten von build parallel, dann läuft build.

3
akarve

Gulp und Node verwenden Versprechen.

So können Sie dies tun:

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

Wenn Sie den gulp-Stream zurückgeben, können Sie mit der then() -Methode einen Rückruf hinzufügen. Alternativ können Sie das native Promise von Node verwenden, um Ihre eigenen Versprechen zu erstellen. Hier benutze ich Promise.all(), um einen Rückruf zu erhalten, der ausgelöst wird, wenn alle Versprechen erfüllt sind.

2
Peter J. Hart