Gulps gulp.watch是否未触发新文件或已删除文件?


151

在全局匹配中编辑文件时,以下Gulpjs任务可以正常工作:

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

但是,对于新文件或已删除文件,它不起作用(不会触发)。有什么我想念的吗?

编辑:即使使用grunt-watch插件,它似乎也不起作用:

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

编辑:解决了,就是这个问题。以./(的值为src)开头的电子邮件似乎无法在ATM上正常工作。


2
如果您将接受的答案更改为Nestor Urquiza的答案,那就太好了。这是真正的答案,而不是添加其他插件
Justin Noel

@alexk的回答是最简单的,不需要添加gulp-watch,例如gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);
Horse

Answers:


130

编辑:显然gulp.watch现在可以处理新文件或删除的文件。询问问题时没有。

我剩下的答案仍然gulp-watch是:通常是一个更好的解决方案,因为它使您仅可以对已修改的文件执行特定操作,而gulp.watch仅允许您运行完整的任务。对于合理大小的项目,这将很快变得太慢而无法使用。


您什么都不会错过。gulp.watch不适用于新文件或删除的文件。这是专为简单项目设计的简单解决方案。

要查看可以查找新文件的文件,请使用功能更强大gulp-watchplugin。用法如下所示:

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

就个人而言,我建议第一种选择。这样可以加快每个文件的处理速度。只要您不连接任何文件,它在使用livereload进行开发的过程中就可以很好地工作。

您可以使用我的lazypipe,也可以仅使用函数来包装流,stream-combiner如下所示:

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

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

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

更新 2014年10月15日

如下面的@pkyeck所指出的,显然1.0版对gulp-watch格式进行了稍微的更改,因此上述示例现在应为:

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

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

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

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

感谢您的帮助,但仍然无法正常工作。我是Gulp的新手(我使用过Grunt几次),也许我的主要任务是错的……不知道。看到我更新的问题。
gremo

18
github.com/floatdrop/gulp-watch/issues/1以'./'开头的glob不发光。我的src变量正好是“-/”。发现了问题!谢谢!
gremo

1
发现该错误的好方法。希望如果有人遇到它会有所帮助!
OverZealous 2014年

@JHannes您在回复什么?这就是答案的解释。
OverZealous 2014年

2
gulp.start是对非公共API方法的调用。还有另一种执行任务的方法吗?
理查德·科莱特

87

双方gulp.watch()require('gulp-watch')()会引发然而,对于新/删除的文件,如果不使用绝对目录。在我的测试中,我没有使用"./"相对目录BTW。

如果整个目录都被删除,两者都不会触发。

   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
优秀而简单的答案。
Edgar Martinez

3
是的-这么多gulp例子都是从./他们的路径开始的-实际上这似乎是一种不好的做法-github.com/floatdrop/gulp-watch/issues/1
rmorse 2015年

1
这次真是万分感谢。我只是绞尽脑汁,试图gulp-watch正常工作以触发新文件或已删除文件。没必要!gulp.watch做这个。./从路径中删除全部可清除问题。太棒了
The Qodesmith

2
这可能是正确的答案-并不是真的想安装另一个插件来观看。从我所有的glob中删除./,效果很好!谢谢!
0Neji

1
这是最好的答案,不需要额外的模块,也不需要了解疯狂的语法。
realappie '16

57

如果src是绝对路径(以开头/),则您的代码将不会检测到新文件或已删除文件。但是仍然有一种方法:

代替:

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

写:

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

它会工作!


12
{ cwd: src }提示是我的解决方案。非常感谢你!
–wireolphin

1
非常感谢@alexk,{cwd:src}解决了我的问题。
kaxi1993 '02

@DanielTonon是否误将文件放入了数组?应该是watch
Horse

它不能在数组中吗?好吧,那太烂了。排除法呢?如果不将源文件放入数组中,则无法进行排除。
Daniel Tonon

4
好答案。要进一步添加,如果您不想更改每个glob模式,只需{cwd:'./'}按原样添加和保留glob模式,这样它就会变成gulp.watch('src/js/**/*.js', {cwd: './'}, ['scripts']);
Akash

7

全局文件必须指定一个单独的基本目录,并且不能在全局文件本身中指定该基本位置。

如果有lib/*.js,它将在当前工作目录下查找process.cwd()

Gulp使用Gaze监视文件,在Gulp API文档中我们看到可以将Gaze特定的选项传递给watch函数:gulp.watch(glob[, opts], tasks)

现在,在Gaze文档中,我们可以找到当前的工作目录(glob基本目录)cwd

这导致我们得出亚历山大的答案: gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);


3

我知道这是一个比较老的问题,但是我想我会提出我想出的解决方案。我发现没有任何gulp插件会通知我新文件或重命名的文件。因此,我最终将单片眼镜包裹在便利功能中。

这是该函数的用法示例:

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

我应该注意gulpStart也是我做的一个便捷函数。

这是实际的监视模块。

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

很简单,是吗?可以在我的gulp入门工具包中找到整个内容:https//github.com/chrisdavies/gulp_starter_kit


1
嘿,伙计,没有足够的人为此提供道具!它就像一种魅力,非常感谢。(答案省略了“ gulpStart”的作用,因此,如果有人感兴趣的话,请访问该链接并转到该utils文件夹可能会造成混淆。)
Augie Gardner


0

您应该对新文件/重命名文件/删除文件使用“ gulp-watch”而不是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));
    });
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.