Gulps gulp.watch não é acionado para arquivos novos ou excluídos?

151

A tarefa Gulpjs a seguir funciona bem ao editar arquivos na correspondência 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');
});

No entanto, ele não funciona (não é acionado) para arquivos novos ou excluídos. Tem algo que estou perdendo?

EDIT : mesmo usando o plugin grunt-watch, parece não funcionar:

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

Edição : Resolvido, foi esse problema . Os globos que começam com ./(esse era o valor de src) parecem não funcionar no caixa eletrônico.

gremo
fonte
2
Seria ótimo se você alterasse a resposta aceita da Nestor Urquiza. É a resposta real aqui, em vez de adicionar um plugin adicional
Justin Noel
a resposta de @alexk foi a mais simples e não exigiu a adição de gulp-watch, por exemplogulp.watch('js/**/*.js', {cwd: src}, ['scripts']);
cavalo

Respostas:

130

Editar: Aparentemente gulp.watch, agora funciona com arquivos novos ou excluídos. Não aconteceu quando a pergunta foi feita.

O restante da minha resposta ainda permanece: gulp-watchgeralmente é uma solução melhor porque permite executar ações específicas apenas nos arquivos que foram modificados, enquanto gulp.watchapenas permite executar tarefas completas. Para um projeto de tamanho razoável, isso rapidamente se tornará lento demais para ser útil.


Você não está perdendo nada. gulp.watchnão funciona com arquivos novos ou excluídos. É uma solução simples projetada para projetos simples.

Para ver arquivos que podem procurar novos arquivos, use ogulp-watch plug in , que é muito mais poderoso. O uso fica assim:

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

Pessoalmente, recomendo a primeira opção. Isso permite processos muito mais rápidos por arquivo. Funciona muito bem durante o desenvolvimento com o carregamento do fígado, desde que você não esteja concatenando nenhum arquivo.

Você pode agrupar seus fluxos usando minha lazypipebiblioteca ou simplesmente usando uma função e stream-combinerassim:

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

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

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

ATUALIZAR 15 de outubro de 2014

Como apontado por @pkyeck abaixo, aparentemente a versão 1.0 gulp-watchmudou ligeiramente o formato, portanto os exemplos acima devem ser agora:

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

e

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

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

watch('src/scripts/**/*.js')
        .pipe(scriptsPipeline());
OverZealous
fonte
Agradecemos por ajudar, mas ainda não conseguimos fazê-lo funcionar. Sou novo no Gulp (já usei o Grunt algumas vezes) e talvez minha tarefa principal esteja errada ... não sei. Veja minha pergunta atualizada.
Gremo
18
github.com/floatdrop/gulp-watch/issues/1 globs começando com './' não emitindo. Minha variável src é exatamente '- /'. Encontrou o problema! Obrigado!
Gremo
1
Boa captura em encontrar esse bug. Espero que ajude se mais alguém o encontrar!
22714 OverZealous
@JHannes O que você está respondendo? É isso que esta resposta está explicando.
OverZealous
2
gulp.start é uma chamada para um método de API não público. Existe outra maneira de executar tarefas?
Richard Collette
87

Ambos gulp.watch()e require('gulp-watch')()irá desencadear para arquivos novos / excluídos no entanto, não se você usar diretórios absolutos. Nos meus testes, não usei "./"para diretórios relativos BTW.

Ambos não serão acionados se diretórios inteiros forem excluídos.

   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');
   //});
Nestor Urquiza
fonte
2
Excelente e simples resposta.
Edgar Martinez
3
yup - tantos exemplos gole lá fora, começar com ./em seus caminhos - na verdade, parece que a má prática - github.com/floatdrop/gulp-watch/issues/1
rmorse
1
Obrigado por isso. Eu estava apenas destruindo meu cérebro tentando começar a gulp-watchfuncionar corretamente para acionar novos arquivos ou arquivos excluídos. Não há necessidade! gulp.watchfaz isso. A remoção de todos ./os caminhos solucionou problemas. Impressionante.
O Qodesmith
2
Esta provavelmente deve ser a resposta certa - não gostava de instalar outro plugin para assistir. Removido o ./ de todos os meus globs e funcionou perfeitamente! Obrigado!
precisa saber é o seguinte
1
Esta é a melhor resposta, não é necessário nenhum módulo extra ou entendimento da sintaxe maluca.
Realappie 31/08/16
57

Se srcfor um caminho absoluto (começando com /), seu código não detectará arquivos novos ou excluídos. No entanto, ainda há uma maneira:

Ao invés de:

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

escrever:

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

e vai funcionar!

alexk
fonte
12
A { cwd: src }dica foi minha solução. Muito obrigado!
Wiredolphin
1
Muito obrigado @alexk, {cwd: src} resolveu meu problema.
kaxi1993
@DanielTonon você colocou dentro de uma matriz de arquivos por engano? deve ser um parâmetro direto dewatch
Horse
Não pode estar em uma matriz? Bem, isso é péssimo. E as exclusões? Não é possível fazer gobbing com exclusões sem colocar os arquivos de origem em uma matriz.
precisa
4
Ótima resposta. Para adicionar ainda mais, se você não quer mudar todos os padrões glob, basta adicionar {cwd:'./'}e deixar o padrão glob como é por isso se tornariagulp.watch('src/js/**/*.js', {cwd: './'}, ['scripts']);
Akash
7

Os globos devem ter um diretório base separado especificado e esse local base não deve ser especificado no próprio globo.

Se você tiver lib/*.js, ele procurará sob o diretório de trabalho atual, que éprocess.cwd()

O Gulp usa o Gaze para assistir arquivos e, no documento da API do Gulp , vemos que podemos passar opções específicas do Gaze para a função de observação:gulp.watch(glob[, opts], tasks)

Agora, no documento do Gaze , podemos descobrir que o diretório de trabalho atual (glob base dir) é a cwdopção.

O que nos leva à resposta de alexk: gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);

Peter Perron
fonte
3

Sei que essa é uma pergunta mais antiga, mas pensei em lançar a solução que me veio à cabeça. Nenhum dos plugins do gulp que encontrei me notificaria de arquivos novos ou renomeados. Então, acabei envolvendo o monóculo em uma função de conveniência.

Aqui está um exemplo de como essa função é usada:

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

Devo observar que o gulpStart também é uma função de conveniência que eu criei.

E aqui está o módulo de relógio 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
  });
};

Bem simples, né? A coisa toda pode ser encontrada no meu kit para iniciantes do gulp: https://github.com/chrisdavies/gulp_starter_kit

Christopher Davies
fonte
1
Ei amigo, poucas pessoas deram adereços para isso! Funciona como um encanto, muito obrigado. (As folhas de resposta para fora o que "gulpStart" faz, por isso pode ser confuso, se alguém estiver interessado, basta visitar o link e vá para a utilspasta)
Augie Gardner
1

É importante observar que parece que o gulp.watch apenas relata arquivos alterados e excluídos no Windows, mas escuta arquivos novos e excluídos por padrão no OSX:

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

Brian Ogden
fonte
0

Você deve usar 'gulp-watch' para arquivos novos / renomeados / excluídos, em vez 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
fonte