【问题标题】:Gulps gulp.watch not triggered for new or deleted files?Gulps gulp.watch 不会为新文件或已删除文件触发?
【发布时间】:2014-04-18 22:46:36
【问题描述】:

在全局匹配中编辑文件时,以下 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');
    });
});

编辑:已解决,它是this issue。以./(即src 的值)开头的 Glob 似乎无法在 ATM 上运行。

【问题讨论】:

  • 如果您将接受的答案更改为来自 Nestor Urquiza 的答案,那就太好了。这是真正的答案,而不是添加额外的插件
  • @alexk 的回答是最简单的,不需要加gulp-watch,例如gulp.watch('js/**/*.js', {cwd: src}, ['scripts']);

标签: javascript node.js gulp


【解决方案1】:

你应该对新的/重命名的/删除的文件使用 '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));
    });
});

【讨论】:

    【解决方案2】:

    需要注意的是,gulp.watch 似乎只报告 Windows 上更改和删除的文件,但默认情况下在 OSX 上侦听新文件和删除的文件:

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

    【讨论】:

      【解决方案3】:

      必须指定一个单独的基目录,并且不得在 glob 本身中指定基位置。

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

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

      现在在Gaze doc 中我们可以发现当前工作目录(glob 基本目录)是cwd 选项。

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 优秀而简单的答案。
        • 是的 - 有很多 gulp 示例在他们的路径中以 ./ 开头 - 实际上这似乎是一种不好的做法 - github.com/floatdrop/gulp-watch/issues/1
        • 谢谢你。我只是绞尽脑汁试图让gulp-watch 正常工作以触发新文件或已删除文件。没必要! gulp.watch 这样做。从路径中删除所有 ./ 清除了问题。太棒了。
        • 这应该是正确的答案 - 并不想安装另一个插件来观看。从我所有的 glob 中删除 ./ 并完美运行!谢谢!
        • 这是最好的答案,不需要额外的模块或理解疯狂的语法。
        【解决方案5】:

        如果src 是绝对路径(以/ 开头),您的代码将不会检测到新文件或已删除文件。不过还是有办法的:

        代替:

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

        写:

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

        它会起作用的!

        【讨论】:

        • { cwd: src } 提示是我的解决方案。非常感谢!
        • 非常感谢@alexk,{ cwd: src } 解决了我的问题。
        • @DanielTonon 您是否错误地放入了一个文件数组?应该是watch的直接参数
        • 不能在数组中?那太糟糕了。排除法呢?如果不将源文件放入数组中,就不可能使用排除项。
        • 很好的答案。要进一步添加,如果您不想更改每个 glob 模式,只需添加 {cwd:'./'} 并保持 glob 模式不变,这样它将变为 gulp.watch('src/js/**/*.js', {cwd: './'}, ['scripts']);
        【解决方案6】:

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

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


        你没有错过任何东西。 gulp.watch 不适用于新文件或已删除文件。这是一个为简单项目设计的简单解决方案。

        要获得可以查找新文件的文件监视,请使用功能更强大的the gulp-watch plugin。用法如下所示:

        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 的开发过程中效果很好。

        您可以使用 my lazypipe library 或简单地使用函数和 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 所指出的,显然gulp-watch 的1.0 版本稍微改变了格式,所以上面的例子现在应该是:

        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),也许我的主要任务是错误的……不知道。请参阅我更新的问题。
        • github.com/floatdrop/gulp-watch/issues/1 以 './' 开头的全局不发射。我的 src 变量正是“-/”。发现问题了!谢谢!
        • 很好地发现了那个错误。希望如果其他人遇到它会有所帮助!
        • @JHannes 你在回复什么?这就是这个答案所要解释的。
        • gulp.start 是对非公共 API 方法的调用。是否有其他方式来执行任务?
        【解决方案7】:

        我知道这是一个较老的问题,但我想我会提出我想出的解决方案。我发现的所有 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

        【讨论】:

        • 嘿伙计,没有足够的人为此提供道具!它就像一个魅力,非常感谢你。 (答案省略了“gulpStart”的作用,因此可能会造成混淆,如果有人感兴趣,只需访问链接并前往utils 文件夹)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-02
        • 2013-04-29
        • 1970-01-01
        • 1970-01-01
        • 2014-09-06
        • 1970-01-01
        相关资源
        最近更新 更多