Gulps gulp.watch n'est pas déclenché pour les fichiers nouveaux ou supprimés?


151

La tâche Gulpjs suivante fonctionne correctement lors de l'édition de fichiers dans la correspondance globale:

// watch task.
gulp.task('watch', ['build'], function () {
    gulp.watch(src + '/js/**/*.js', ['scripts']);
    gulp.watch(src + '/img//**/*.{jpg,jpeg,png,gif}', ['copy:images']);
    gulp.watch(src + '/less/*.less', ['styles']);
    gulp.watch(src + '/templates/**/*.{swig,json}', ['html']);
});

// build task.
gulp.task('build', ['clean'], function() {
    return gulp.start('copy', 'scripts', 'less', 'htmlmin');
});

Cependant, cela ne fonctionne pas (il n'est pas déclenché) pour les fichiers nouveaux ou supprimés. Y a-t-il quelque chose qui me manque?

EDIT : même en utilisant le plugin grunt-watch, cela ne semble pas fonctionner:

gulp.task('scripts', function() {
    return streamqueue(
        { objectMode: true },
        gulp.src([
            vendor + '/jquery/dist/jquery.min.js',
            vendor + '/bootstrap/dist/js/bootstrap.min.js'
        ]),
        gulp.src([
            src + '/js/**/*.js'
        ]).pipe(plugins.uglify())
    )
    .pipe(plugins.concat(pkg.name + '.min.js'))
    .pipe(gulp.dest(dest + '/js/'));
});

gulp.task('watch', ['build'], function () {
    plugins.watch({glob: src + '/js/**/*.js'}, function () {
        gulp.start('scripts');
    });
});

EDIT : Résolu, c'était ce problème . Globs commençant par ./(c'était la valeur de src) ne semble pas fonctionner ATM.


2
Ce serait formidable si vous changiez la réponse acceptée par celle de Nestor Urquiza. C'est la vraie réponse ici plutôt que d'ajouter un plugin supplémentaire
Justin Noel

la réponse de @alexk était la plus simple et ne nécessitait pas l'ajout de gulp-watch, par exemplegulp.watch('js/**/*.js', {cwd: src}, ['scripts']);
Cheval

Réponses:


130

Edit: fonctionne apparemment gulp.watchavec des fichiers nouveaux ou supprimés maintenant. Ce n'était pas le cas lorsque la question a été posée.

Le reste de ma réponse est toujours valable: gulp-watchest généralement une meilleure solution car elle vous permet d'effectuer des actions spécifiques uniquement sur les fichiers qui ont été modifiés, tout en gulp.watchvous permettant uniquement d'exécuter des tâches complètes. Pour un projet d'une taille raisonnable, cela deviendra vite trop lent pour être utile.


Vous ne manquez rien. gulp.watchne fonctionne pas avec les fichiers nouveaux ou supprimés. C'est une solution simple conçue pour des projets simples.

Pour obtenir une surveillance de fichiers capable de rechercher de nouveaux fichiers, utilisez le gulp-watchplugin , qui est beaucoup plus puissant. L'utilisation ressemble à ceci:

var watch = require('gulp-watch');

// in a task
watch({glob: <<glob or array of globs>> })
        .pipe( << add per-file tasks here>> );

// if you'd rather rerun the whole task, you can do this:
watch({glob: <<glob or array of globs>>}, function() {
    gulp.start( <<task name>> );
});

Personnellement, je recommande la première option. Cela permet des processus par fichier beaucoup plus rapides. Cela fonctionne très bien pendant le développement avec livereload tant que vous ne concaténez aucun fichier.

Vous pouvez encapsuler vos flux soit en utilisant ma lazypipebibliothèque , soit simplement en utilisant une fonction et stream-combinercomme ceci:

var combine = require('stream-combiner');

function scriptsPipeline() {
    return combine(coffeeescript(), uglify(), gulp.dest('/path/to/dest'));
}

watch({glob: 'src/scripts/**/*.js' })
        .pipe(scriptsPipeline());

MISE À JOUR 15 octobre 2014

Comme indiqué par @pkyeck ci-dessous, apparemment la version 1.0 de gulp-watcha légèrement changé le format, donc les exemples ci-dessus devraient maintenant être:

var watch = require('gulp-watch');

// in a task
watch(<<glob or array of globs>>)
        .pipe( << add per-file tasks here>> );

// if you'd rather rerun the whole task, you can do this:
watch(<<glob or array of globs>>, function() {
    gulp.start( <<task name>> );
});

et

var combine = require('stream-combiner');

function scriptsPipeline() {
    return combine(coffeeescript(), uglify(), gulp.dest('/path/to/dest'));
}

watch('src/scripts/**/*.js')
        .pipe(scriptsPipeline());

Merci de votre aide mais n'arrive toujours pas à le faire fonctionner. Je suis nouveau sur Gulp (j'ai utilisé Grunt plusieurs fois) et peut-être que ma tâche principale est erronée ... je ne sais pas. Voir ma question mise à jour.
gremo

18
github.com/floatdrop/gulp-watch/issues/1 globs commençant par './' n'émettant pas. Ma variable src est exactement '- /'. Trouvé le problème! Merci!
gremo

1
Bonne prise pour trouver ce bug. J'espère que cela aidera si quelqu'un d'autre le rencontre!
OverZealous

@JHannes À quoi répondez-vous? C'est ce que cette réponse explique.
OverZealous

2
gulp.start est un appel à une méthode d'API non publique. Existe-t-il une autre façon d'exécuter des tâches?
Richard Collette

87

Les deux gulp.watch()et require('gulp-watch')()se déclencheront pour les fichiers nouveaux / supprimés, mais pas si vous utilisez des répertoires absolus. Dans mes tests, je n'ai pas utilisé "./"pour les répertoires relatifs BTW.

Les deux ne se déclencheront pas si des répertoires entiers sont supprimés.

   var watch = require('gulp-watch');
   //Wont work for new files until gaze is fixed if using absolute dirs. It  won't trigger if whole directories are deleted though.
   //gulp.watch(config.localDeploy.path + '/reports/**/*', function (event) {

   //gulp.watch('src/app1/reports/**/*', function (event) {
   // console.log('*************************** Event received in gulp.watch');
   // console.log(event);
   // gulp.start('localDeployApp');
   });

   //Won't work for new files until gaze is fixed if using absolute dirs. It  won't trigger if whole directories are deleted though. See https://github.com/floatdrop/gulp-watch/issues/104
   //watch(config.localDeploy.path + '/reports/**/*', function() {

   watch('src/krfs-app/reports/**/*', function(event) {
      console.log("watch triggered");
      console.log(event);
      gulp.start('localDeployApp');
   //});

2
Excellente et simple réponse.
Edgar Martinez

3
oui - tant d'exemples de gulp commencent par ./leur chemin - en fait, cela semble être une mauvaise pratique - github.com/floatdrop/gulp-watch/issues/1
rmorse

1
Merci pour ça. Je me creusais la tête en essayant de gulp-watchfonctionner correctement pour déclencher de nouveaux fichiers ou des fichiers supprimés. Ce n'est pas nécessaire! gulp.watchest ce que ca. Tout supprimer ./des chemins a résolu les problèmes. Impressionnant.
The Qodesmith

2
Cela devrait probablement être la bonne réponse - je n'avais pas vraiment envie d'installer un autre plugin à regarder. Supprimé le ./ de tous mes globs et a parfaitement fonctionné! Merci!
0Neji le

1
C'est la meilleure réponse, aucun module supplémentaire requis ou compréhension d'une syntaxe folle.
realappie

57

S'il srcs'agit d'un chemin absolu (commençant par /), votre code ne détectera pas les fichiers nouveaux ou supprimés. Cependant, il y a encore un moyen:

Au lieu de:

gulp.watch(src + '/js/**/*.js', ['scripts']);

écrire:

gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);

et cela fonctionnera!


12
L' { cwd: src }indice était ma solution. Merci beaucoup!
wiredolphin

1
Merci beaucoup @alexk, {cwd: src} a résolu mon problème.
kaxi1993

@DanielTonon avez-vous mis dans un tableau de fichiers par erreur? devrait être un paramètre direct dewatch
Cheval

Ça ne peut pas être dans un tableau? Eh bien, ça craint. Qu'en est-il des exclusions? Il n'est pas possible de faire du gobbing avec des exclusions sans placer les fichiers source dans un tableau.
Daniel Tonon

4
Très bonne réponse. Pour ajouter plus, si vous ne voulez pas changer chaque modèle de glob, ajoutez simplement {cwd:'./'}et laissez le modèle de glob comme tel pour qu'il deviennegulp.watch('src/js/**/*.js', {cwd: './'}, ['scripts']);
Akash

7

Globs doit avoir un répertoire de base distinct spécifié et cet emplacement de base ne doit pas être spécifié dans le glob lui-même.

Si vous avez lib/*.js, il regardera sous le répertoire de travail actuel qui estprocess.cwd()

Gulp utilise Gaze pour regarder les fichiers et dans la documentation de l'API Gulp, nous voyons que nous pouvons transmettre des options spécifiques à Gaze à la fonction de surveillance:gulp.watch(glob[, opts], tasks)

Maintenant, dans la documentation Gaze, nous pouvons trouver que le répertoire de travail actuel (répertoire de base glob) est l' cwdoption.

Ce qui nous amène à la réponse d'Alexk: gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);


3

Je sais que c'est une question plus ancienne, mais j'ai pensé jeter la solution que j'ai trouvée. Aucun des plugins gulp que j'ai trouvés ne m'avertirait de nouveaux fichiers ou de fichiers renommés. J'ai donc fini par emballer le monocle dans une fonction de commodité.

Voici un exemple d'utilisation de cette fonction:

watch({
    root: config.src.root,
    match: [{
      when: 'js/**',
      then: gulpStart('js')
    }, {
      when: '+(scss|css)/**',
      then: gulpStart('css')
    }, {
      when: '+(fonts|img)/**',
      then: gulpStart('assets')
    }, {
      when: '*.+(html|ejs)',
      then: gulpStart('html')
    }]
  });

Je dois noter que gulpStart est également une fonction pratique que j'ai créée.

Et voici le module de montre réel.

module.exports = function (options) {
  var path = require('path'),
      monocle = require('monocle'),
      minimatch = require('minimatch');

  var fullRoot = path.resolve(options.root);

  function onFileChange (e) {
    var relativePath = path.relative(fullRoot, e.fullPath);

    options.match.some(function (match) {
      var isMatch = minimatch(relativePath, match.when);
      isMatch && match.then();
      return isMatch;
    });
  }

  monocle().watchDirectory({
    root: options.root,
    listener: onFileChange
  });
};

Assez simple, hein? Le tout peut être trouvé dans mon kit de démarrage gulp: https://github.com/chrisdavies/gulp_starter_kit


1
Hé mon pote, pas assez de gens ont donné des accessoires pour ça! Cela fonctionne comme un charme, merci beaucoup. (La réponse ne tient pas compte de ce que fait "gulpStart", donc cela peut être déroutant, si quelqu'un est intéressé, visitez simplement le lien et dirigez-vous vers le utilsdossier)
Augie Gardner


0

Vous devriez utiliser 'gulp-watch' pour les fichiers nouveaux / renommés / supprimés au lieu de gulp.watch

var gulpwatch = require('gulp-watch');
var source = './assets',  
destination = './dest';
gulp.task('copy-changed-assets', function() {
    gulpwatch(source+'/**/*', function(obj){
        gulp.src( obj.path, { "base": source})
        .pipe(gulp.dest(destination));
    });
});
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.