dans l'extrait comme ceci:
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"
Dans la tâche develop
, je veux exécuter clean
et ensuite, exécuter coffee
, puis exécuter autre chose. Mais je ne peux pas comprendre cela. Cette pièce ne fonctionne pas. S'il vous plaît donnez votre avis.
Ce n'est pas encore une version officielle, mais la prochaine version de Gulp 4.0 vous permet d'effectuer facilement des tâches synchrones avec gulp.series. Vous pouvez simplement le faire comme ceci:
gulp.task('develop', gulp.series('clean', 'coffee'))
J'ai trouvé un bon article de blog qui explique comment mettre à niveau et utiliser ces fonctionnalités intéressantes: migration vers gulp 4 par exemple
Par défaut, gulp exécute des tâches simultanément, sauf si elles ont des dépendances explicites. Ce n'est pas très utile pour des tâches telles que clean
, pour lesquelles vous ne voulez pas dépendre, mais dont vous avez besoin avant.
J'ai écrit le plugin run-sequence
spécialement pour résoudre ce problème avec gulp. Après l'avoir installé, utilisez-le comme ceci:
var runSequence = require('run-sequence');
gulp.task('develop', function(done) {
runSequence('clean', 'coffee', function() {
console.log('Run something else');
done();
});
});
Vous pouvez lire les instructions complètes sur le paquet README - il prend également en charge l’exécution simultanée de certains ensembles de tâches.
Veuillez noter que ceci sera (effectivement) corrigé dans la prochaine version majeure de gulp , car ils éliminent complètement le classement automatique des dépendances et fournissent des outils similaires à run-sequence
pour vous permettre de spécifiez l'ordre d'exécution comme vous le souhaitez.
Cependant, il s’agit d’un changement radical majeur. Il n’ya donc aucune raison d’attendre lorsque vous pouvez utiliser run-sequence
aujourd’hui.
La seule bonne solution à ce problème peut être trouvée dans la documentation gulp qui peut être trouvée ici
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']);
J'ai généré une application nœud/gulp à l'aide du générateur générateur-gulp-webapp Yeoman. Il traitait le "casse-tête propre" de cette façon (en traduisant les tâches originales mentionnées dans la question):
gulp.task('develop', ['clean'], function () {
gulp.start('coffee');
});
run-sequence est le moyen le plus clair (au moins jusqu'à ce que Gulp 4.0 soit publié)
Avec run-sequence , votre tâche ressemblera à ceci:
var sequence = require('run-sequence');
/* ... */
gulp.task('develop', function (done) {
sequence('clean', 'coffee', done);
});
Mais si vous (pour une raison quelconque) préférez ne pas l'utiliser, la méthode gulp.start
vous aidera :
gulp.task('develop', ['clean'], function (done) {
gulp.on('task_stop', function (event) {
if (event.task === 'coffee') {
done();
}
});
gulp.start('coffee');
});
Remarque: Si vous ne démarrez que la tâche sans écouter le résultat, la tâche develop
se terminera plus tôt que coffee
, et cela peut être déroutant.
Vous pouvez également supprimer le programme d'écoute d'événement lorsque vous n'en avez pas besoin
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');
});
Considérez un autre événement task_err
que vous souhaitez peut-être écouter. task_stop
est déclenché à la fin, tandis que task_err
apparaît en cas d'erreur.
Vous pouvez également vous demander pourquoi il n’existe pas de documentation officielle pour gulp.start()
. Cette réponse d'un membre de gulp explique les choses:
gulp.start
est délibérément non documenté car il peut entraîner des fichiers de construction compliqués et nous ne voulons pas que les gens l'utilisent
(source: https://github.com/gulpjs/gulp/issues/426#issuecomment-41208007 )
Selon les documents Gulp:
Vos tâches sont-elles en cours d'exécution avant la fin des dépendances? Assurez-vous que vos tâches de dépendance utilisent correctement les astuces d'exécution asynchrone: recevez un rappel ou renvoyez une promesse ou un flux d'événements.
Pour exécuter votre séquence de tâches de manière synchrone:
gulp.src
) à gulp.task
pour informer la tâche de la fin du flux.gulp.task
.Voir le code révisé:
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"
J'avais exactement le même problème et la solution s'est révélée assez facile pour moi. Modifiez fondamentalement votre code comme suit et cela devrait fonctionner. NOTE: le retour avant gulp.src a fait toute la différence pour moi.
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"
essayé toutes les solutions proposées, toutes semblent avoir leurs propres problèmes.
Si vous regardez réellement dans la source de l'orchestrateur, en particulier dans l'implémentation .start()
, vous verrez que si le dernier paramètre est une fonction, il le traitera comme un rappel.
J'ai écrit cet extrait pour mes propres tâches:
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" ));
Je cherchais cette réponse pendant un moment. Maintenant, je l'ai dans la documentation officielle de gulp.
Si vous souhaitez effectuer une tâche d'absorption lorsque la dernière est terminée, vous devez renvoyer un flux:
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));
});
Pour moi, la tâche de minify n'était pas exécutée après la concaténation car elle attendait une entrée concaténée et elle n'a pas été générée à plusieurs reprises.
J'ai essayé d'ajouter une tâche par défaut dans l'ordre d'exécution et cela n'a pas fonctionné. Cela fonctionnait après avoir ajouté juste un return
pour chaque tâche et obtenir la minification à l'intérieur de gulp.start()
comme ci-dessous.
/**
* 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']);
Faites simplement coffee
dépendre de clean
, et develop
dépend de coffee
:
gulp.task('coffee', ['clean'], function(){...});
gulp.task('develop', ['coffee'], function(){...});
Le dispatch est maintenant en série: clean
→ coffee
→ develop
. Notez que l'implémentation de clean
et celle de coffee
doivent accepter un rappel, "afin que le moteur sache quand il ' Tout sera fait " :
gulp.task('clean', function(callback){
del(['dist/*'], callback);
});
En conclusion, vous trouverez ci-dessous un modèle de groupe simple pour un clean
synchrone suivi de dépendances de construction asynchrones :
//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 est suffisamment intelligent pour exécuter clean
exactement une fois par build
, quel que soit le nombre de dépendances de build
dépendant de clean
. Comme indiqué ci-dessus, clean
est une barrière de synchronisation; toutes les dépendances de build
sont exécutées en parallèle, puis build
est exécuté.
Gulp et Node utilisent promesses.
Donc, vous pouvez faire ceci:
// ... 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();
});
});
});
Si vous renvoyez le flux gulp, vous pouvez utiliser la méthode then()
pour ajouter un rappel. Alternativement, vous pouvez utiliser le Promise
natif de Node pour créer vos propres promesses. Ici, j'utilise Promise.all()
pour avoir un rappel qui se déclenche lorsque toutes les promesses sont résolues.