¿Gulps gulp.watch no se activa para archivos nuevos o eliminados?

151

La siguiente tarea de Gulpjs funciona bien al editar archivos en la coincidencia global:

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

Sin embargo, no funciona (no se activa) para archivos nuevos o eliminados. ¿Se me escapa algo?

EDITAR : incluso usando el complemento grunt-watch parece que no funciona:

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

EDITAR : Resuelto, fue este problema . Parece que los globos que comienzan con ./(ese era el valor de src) no funcionan en ATM.

gremo
fuente
2
Sería genial si cambiara la respuesta aceptada a la de Néstor Urquiza. Es la verdadera respuesta aquí en lugar de agregar un complemento adicional
Justin Noel
la respuesta de @alexk fue la más simple y no requirió la adición de gulp-watch, por ejemplo,gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);
Horse

Respuestas:

130

Editar: aparentemente gulp.watchfunciona con archivos nuevos o eliminados ahora. No fue así cuando se hizo la pregunta.

El resto de mi respuesta sigue en pie: gulp-watchgeneralmente es una mejor solución porque le permite realizar acciones específicas solo en los archivos que se han modificado, mientras que gulp.watchsolo le permite ejecutar tareas completas. Para un proyecto de un tamaño razonable, esto se volverá demasiado lento para ser útil.


No te falta nada. gulp.watchno funciona con archivos nuevos o eliminados. Es una solución simple diseñada para proyectos simples.

Para ver archivos que puedan buscar archivos nuevos, use el gulp-watchcomplemento , que es mucho más potente. El uso se ve así:

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

Personalmente, recomiendo la primera opción. Esto permite procesos por archivo mucho más rápidos. Funciona muy bien durante el desarrollo con livereload siempre que no esté concatenando ningún archivo.

Puede concluir sus transmisiones utilizando mi lazypipebiblioteca o simplemente utilizando una función y stream-combinerasí:

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

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

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

ACTUALIZACIÓN 15 de octubre de 2014

Como señaló @pkyeck a continuación, aparentemente la versión 1.0 de gulp-watchcambió ligeramente el formato, por lo que los ejemplos anteriores ahora deberían ser:

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

y

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

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

watch('src/scripts/**/*.js')
        .pipe(scriptsPipeline());
Demasiado entusiasta
fuente
Gracias por ayudar, pero todavía no puedo hacer que funcione. Soy nuevo en Gulp (he usado Grunt un par de veces) y tal vez mi tarea principal está mal ... no sé. Ver mi pregunta actualizada.
gremo
18
github.com/floatdrop/gulp-watch/issues/1 globos que comienzan con './' no emiten. Mi variable src es exactamente '- /'. Encontrado el problema! ¡Gracias!
gremo
1
Buen truco para encontrar ese error. ¡Espero que ayude si alguien más lo encuentra!
OverZealous
@JHannes ¿A qué estás respondiendo? Eso es lo que esta respuesta está explicando.
OverZealous
2
gulp.start es una llamada a un método API no público. ¿Hay otra forma de ejecutar tareas?
Richard Collette
87

Ambos gulp.watch()y require('gulp-watch')()se activarán para archivos nuevos / eliminados, sin embargo, no si utiliza directorios absolutos. En mis pruebas no utilicé "./"para directorios relativos BTW.

Sin embargo, ambos no se activarán si se eliminan directorios completos.

   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');
   //});
Néstor Urquiza
fuente
2
Excelente y simple respuesta.
Edgar Martinez
3
yup - tantos ejemplos trago por ahí comienzan con ./a su paso - en realidad parece como una mala práctica - github.com/floatdrop/gulp-watch/issues/1
rmorse
1
Gracias por esto. Estaba simplemente aturdiéndome el cerebro tratando de gulp-watchfuncionar correctamente para activar nuevos archivos o archivos eliminados. ¡No hay necesidad! gulp.watchHaz esto. Al eliminar todo ./de las rutas se resolvieron los problemas. Increíble.
The Qodesmith
2
Probablemente esta debería ser la respuesta correcta: no me gustó instalar otro complemento para ver. ¡Eliminé el ./ de todos mis globos y funcionó perfectamente! ¡Gracias!
0Neji
1
Esta es la mejor respuesta, no se requiere ningún módulo adicional o comprensión de la sintaxis loca.
realappie
57

Si srces una ruta absoluta (empezando por /), su código no detectará archivos nuevos o eliminados. Sin embargo, todavía hay una manera:

En vez de:

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

escribir:

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

y funcionará!

alexk
fuente
12
La { cwd: src }pista fue mi solución. ¡Muchas gracias!
wiredolphin
1
Muchas gracias @alexk, {cwd: src} resolvió mi problema.
kaxi1993
@DanielTonon, ¿metiste dentro de una matriz de archivos por error? debería ser un parámetro directo dewatch
Horse
No puede estar en una matriz? Bueno, eso apesta. ¿Qué pasa con las exclusiones? No es posible hacer saltos con exclusiones sin colocar los archivos de origen en una matriz.
Daniel Tonon
44
Gran respuesta. Para agregar más, si no desea cambiar cada patrón de globo, simplemente agregue {cwd:'./'}y deje el patrón de globo como está para que se convierta engulp.watch('src/js/**/*.js', {cwd: './'}, ['scripts']);
Akash
7

Los globos deben tener un directorio base separado especificado y esa ubicación base no debe especificarse en el globo mismo.

Si es así lib/*.js, se verá debajo del directorio de trabajo actual, que esprocess.cwd()

Gulp usa Gaze para mirar archivos y en el documento API de Gulp vemos que podemos pasar opciones específicas de Gaze a la función de vigilancia:gulp.watch(glob[, opts], tasks)

Ahora en el documento de Gaze podemos encontrar que el directorio de trabajo actual (directorio base de glob) es la cwdopción.

Lo que nos lleva a la respuesta de alexk: gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);

Peter Perron
fuente
3

Sé que esta es una pregunta anterior, pero pensé en lanzar la solución que se me ocurrió. Ninguno de los complementos de Gulp que encontré me notificaría de archivos nuevos o renombrados. Así que terminé envolviendo el monóculo en una función conveniente.

Aquí hay un ejemplo de cómo se usa esa función:

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

Debo señalar que gulpStart también es una función de conveniencia que hice.

Y aquí está el módulo de reloj real.

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

Bastante simple, ¿eh? Todo se puede encontrar en mi kit de inicio de Gulp: https://github.com/chrisdavies/gulp_starter_kit

Christopher Davies
fuente
1
¡Hola amigo, no hay suficientes personas que hayan apoyado esto! Funciona a las mil maravillas, muchas gracias. (La respuesta omite lo que hace "gulpStart", por lo que puede ser confuso, si alguien está interesado, solo visite el enlace y diríjase a la utilscarpeta)
Augie Gardner
1

Es importante tener en cuenta que parece que gulp.watch solo informa los archivos modificados y eliminados en Windows, pero escucha los archivos nuevos y eliminados de forma predeterminada en OSX:

https://github.com/gulpjs/gulp/issues/675

Brian Ogden
fuente
0

Debería usar 'gulp-watch' para archivos nuevos / renombrados / eliminados en lugar 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));
    });
});
Jitendra Saroj
fuente