为什么 grunt-watch 任务说它正在监视 files/directories 我没有在配置中指定?

Why does the grunt-watch task say it is watching files/directories I have not specified in configuration?

我有以下 Gruntfile.js:

module.exports = function (grunt) {

    "use strict";

    grunt.initConfig({
        watch: {
            options: {
              livereload: true
            },
            css: {
                files: ["app.styles.css"]
            },
            js: {
              files: ["app/**/*.js"]
            },
            html: {
              files: ["index.html", "app/**/*.html"]
            }
        },
        connect: {
            server: {
                options: {
                    port: 9000,
                    hostname: "*",
                    livereload: true,
                    open: true
                }
            }
        },
        jshint: {
            files: ["app/**/*.js"]
        }
    });

    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-contrib-watch");
    grunt.loadNpmTasks("grunt-contrib-connect");

    grunt.registerTask("default", ["connect","watch"]);

};

我的申请中有以下结构:

请注意,应用程序、bower_components、css 和图像都在同一级别。

当我 运行 任务 grunt --verbose 时,我看到我的应用程序中还有更多 files/directories 正在被监视,包括 bower_components 和 node_modules 目录。

但我没有指定 g运行t 观看这些 files/directories 中的任何一个。最重要的是,当我修改配置中指定的 css 文件 (app.styles.css) 时,G运行t 不会重新加载应用程序。我认为 g运行t 只查看了我在 Gruntfile.js 中指定的文件,这正是我想要的。为什么 G运行t 看这些额外的 files/directories 而不看我的 app.styles.css 文件?

grunt-contrib-watch uses a node package called gaze。正是凝视构建了文件路径的 watched 对象以供观察,并且对 fs.watch 进行了实际调用。 watched 对象由作为键的目录路径和作为值的后代文件路径和子目录路径的数组构成。具有单个 scripts.js 文件的 watched 对象可能如下所示:

{    
    "C:\{{path_to_your_application_root}}\app\Scripts\": [
        "C:\{{path_to_your_application_root}}\app\Scripts\script.js"
    ]
}

有趣的是,当 Gaze 将文件路径添加到 watched 对象时,它会查找与该文件路径同级的所有目录,然后 将这些目录添加到 watched 对象也!

来自凝视源的相关代码如下:

// add folders into the mix
var readdir = fs.readdirSync(dirname);
for (var j = 0; j < readdir.length; j++) {
    var dirfile = path.join(dirname, readdir[j]);
    if (fs.lstatSync(dirfile).isDirectory()) {
        helper.objectPush(this._watched, dirname, dirfile + path.sep);
    }
}

这样做的结果是,当在应用程序根目录中找到 "index.html" 文件路径时,应用程序根目录中的所有目录(app/、bin/、bower_components/、等)也被添加到 watched 对象中。

您可以通过从手表中删除 "index.html" 来确认这一点,您应该不会再在详细输出中看到所有这些文件夹监视。

这里 link 讨论了为什么凝视库有这种行为。

至于为什么你的 "app.styles.css" 没有 观看:你是否缺少此文件的路径。我在您的应用程序根目录中没有看到 "app.styles.css"。大概是在css/.

所以几个月后回到这个问题后,我终于弄清楚我需要做什么才能让它发挥作用。在 Gruntfile.js 中,您需要在 css 属性 中添加 options: { livereload: true}。我不知道为什么你需要它在 watch 属性 然后又在 css 属性.

使用本地开发服务器和 livereload 的极简主义者 Gruntfile.js 是:

module.exports = function (grunt) {

    "use strict";

    grunt.initConfig({
        watch: {
            options: {
                livereload: true
            },
            css: {
                files: ["css/**/*.css"],

                /*********************************** ADDED THIS ************************/
                options: {
                    livereload: true
                }
            },
            js: {
                files: ["app/**/*.js"]
            },
            html: {
                files: ["index.html", "app/**/*.html"]
            }
        },
        connect: {
            server: {
                options: {
                    port: 9000,
                    hostname: "*",
                    livereload: true,
                    open: true
                }
            }
        },
        jshint: {
            files: ["app/**/*.js"]
        }
    });

    grunt.loadNpmTasks("grunt-contrib-jshint");
    grunt.loadNpmTasks("grunt-contrib-watch");
    grunt.loadNpmTasks("grunt-contrib-connect");

    grunt.registerTask("default", ["connect", "watch"]);
};