如何在Grunt.js中观察多个文件,但只在更改的文件上运行任务

How do you watch multiple files, but only run task on changed file, in Grunt.js?

本文关键字:文件 任务 运行 js Grunt 观察      更新时间:2023-09-26

在学习如何使用grunt时,我试图制作一个简单的咖啡脚本观察程序/编译器。问题是,如果我告诉watch任务监视几个文件,其中一个文件发生了更改,它将把所有文件传递给coffee命令。这意味着,当您更改1个文件时,它将重新编译所有src模式匹配的文件。相反,我只想重新编译与src模式匹配的已更改的单个文件。

这是grunt.js:

module.exports = function(grunt) {
  grunt.initConfig({
    coffee: {
      app: {
        src: ['test/cases/controller/*.coffee'],
        dest: 'tmp',
        options: {
          bare: true,
          preserve_dirs: true
        }
      }
    },
    watch: {
      files: ['<config:coffee.app.src>'],
      tasks: ['coffee:app']
    }
  });
  grunt.loadNpmTasks('grunt-coffee');
  grunt.registerTask('default', 'coffee');
};

这是用咕哝咖啡,基本上是这样的:https://gist.github.com/2373159.

当我运行grunt watch并在test/cases/controller/*.coffee中保存一个文件时,它会编译所有的匹配文件(将它们放在tmp/*中)。

如何使用grunt只编译更改后的文件?

即将推出的(目前正在开发中)v0.4.0a grunt具有grunt.file.watchFiles对象,该对象是专门为此目的而设计的。grunt coffee插件可能已经添加了对该功能的支持,我不确定。

无论哪种方式,如果您有兴趣在项目中尝试grunt的开发中版本,请查看"我何时能够使用开发中功能"X"?常见问题条目。

我在编译less文件时就完成了这项工作。您应该能够稍微处理一下这个配置,让它与coffeescript插件一起工作。感兴趣的部分是grunt.event.on('watch', ...)。在这个事件处理程序中,我正在更新less命令中的files属性,使其仅包含更改后的文件。

path = require('path');
module.exports = function(grunt) {
  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    less: {
      development: {
        options: {
          paths: ["./library/less"],
        },
        files: [
          { src: "./library/less/bootstrap.less", dest: "./library/css/bootstrap.css"},
          { src: "./library/less/app.less", dest: "./library/css/app.css"}
        ]
      }
    },
    watch: {
      styles: {
        files: "./library/less/*",
        tasks: ["less"],
        options: {
          nospawn: true,
        },
      },
    },
  });
  // Event handling
  grunt.event.on('watch', function(action, filepath){
    // Update the config to only build the changed less file.
    grunt.config(['less', 'development', 'files'], [
      {src: filepath, dest: './library/css/' + path.basename(filepath, '.less') + '.css'}
    ]);
  });
  // Load the plugins
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');
  // Tasks
  grunt.registerTask('default', ['watch']);
};

这些答案对我来说都不太有效。如果有人感兴趣,这是我的解决方案(我知道我回答这个问题有点晚了)。

https://gist.github.com/ryansmith94/8569178

在本期中,Kyle Robinson建议使用watch事件。将监视任务nospawn属性设置为true以使其工作非常重要。我修改了他的解决方案以选择性地运行任务:

grunt.event.on('watch', function(action, filepath) {
    if (minimatch(filepath, grunt.config('watch.stylesheets.files'))) {
        grunt.config('compass.dist.options.specify', [filepath]);
    }
    if (minimatch(filepath, grunt.config('watch.scripts.files'))) {
        var uglifySrc = filepath.replace(grunt.config('uglify.dist.cwd'), '');
        grunt.config('jshint.dist.src', [filepath]);
        grunt.config('uglify.dist.src', [uglifySrc]);
    }
});

以下是完整的解决方案:https://gist.github.com/luissquall/5408257

https://github.com/tschaub/grunt-newer类似任务看起来完全一样:

将Grunt任务配置为仅使用更新的文件运行。

剧情简介:更新的任务将配置另一个任务使用src运行a)比dest文件新或b)比上一个文件新的文件成功运行(如果没有dest文件)。示例见下文以及更多细节。

你可以很容易地为任何任务做准备。在您的情况下:

  grunt.loadNpmTasks('grunt-newer');
  grunt.registerTask('default', 'newer:coffee');

Grunt 0.4的新任务是更多的命名任务

让我们给你举个例子!

watch: {
    package1: {
        files: [
            './modules/package1/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
    package2: {
        files: [
            './test_packages/package2/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
    package3: {
        files: [
            './test_packages/package3/**/*.coffee'
        ],
        tasks: ['coffee:package3']
    },
}

要运行所有这些监视任务,只需执行grunt.registerTask("默认"、["myInitialBuild"、"watch"]);

其中myInitialBuild是任何初始构建(所有文件),然后对每个包进行监视。事实上,你可以对每个文件都这样做,但这听起来很糟糕。

任务grunt contrib watch现在支持这一点。

https://npmjs.org/package/grunt-contrib-watch->查找"根据需要编译文件"

grunt.initConfig({
  watch: {
    scripts: {
      files: ['lib/*.js'],
      tasks: ['jshint'],
      options: {
        nospawn: true,
      },
    },
  },
  jshint: {
    all: ['lib/*.js'],
  },
});
// on watch events configure jshint:all to only run on changed file
grunt.event.on('watch', function(action, filepath) {
  grunt.config(['jshint', 'all'], filepath);
});

这样可以防止任务在每次发生更改时编译所有文件。