在咕噜,如果我正在看多个文件和两个或两个以上的变化,我怎么才能只在被更改的文件上运行任务?

我有一个initConfig与这个代码:

 grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), watch: { options: { spawn: false }, coffee: { files: [ 'src/**/*.coffee' ], tasks: ['coffee', 'coffeelint', 'concat', 'qunit'] }, ... coffee: { glob_to_multiple: { expand: true, flatten: false, cwd: '.', src: ['src/**/*.coffee'], ext: '.js' } }, ... grunt.event.on('watch', function (action, filepath) { if (grunt.file.isMatch("**/*.coffee", filepath)) { grunt.config(['coffee', 'glob_to_multiple', 'src'], filepath); } }); 

这应该只编译已经改变的.coffee文件。 这工作很好。 但我只注意到,如果我一次修改多个,它会输出这个:

 Waiting...src\test\resources\app\js\FILE1.coffee src\main\resources\app\js\FILE2.coffee OK >> File "src\test\resources\app\js\FILE1.coffee" changed. >> File "src\main\resources\app\js\FILE2.coffee" changed. Running "coffee:glob_to_multiple" (coffee) task File src/main/resources/app/js/FILE2.js created. ... 

正如你所看到的,我已经更改了两个文件,但它只运行“FILE2.js”上的任务。 我怎样才能避免这一点? 我想要它在FILE1和FILE2上运行coffee:glob_to_multiple ,而不仅仅是其中之一。


注:我很确定文档解释了如何做到这一点:

如果你同时保存多个文件,你可以select一个更强大的方法:

 var changedFiles = Object.create(null); var onChange = grunt.util._.debounce(function() { grunt.config(['jshint', 'all'], Object.keys(changedFiles)); changedFiles = Object.create(null); }, 200); grunt.event.on('watch', function(action, filepath) { changedFiles[filepath] = action; onChange(); }); 

遵循这个文档,我对这个代码做了这个改变:

 var changedFiles = Object.create(null); var onChange = grunt.util._.debounce(function() { grunt.config(['coffee', 'glob_to_multiple', 'src'], Object.keys(changedFiles)); changedFiles = Object.create(null); }, 200); grunt.event.on('watch', function(action, filepath) { if (grunt.file.isMatch("**/*.coffee", filepath)) { changedFiles[filepath] = action; onChange(); } }); 

而事情正是我想要的方式。 但我不确定这是如何工作的。 有人可以向我解释吗?

这是一个非常复杂的解决scheme,使用Lo-Dash debounce ;-)(在一秒钟内)

知道,当你使用你的旧代码:

  grunt.config(['coffee', 'glob_to_multiple', 'src'], filepath); 

指导Grunt使用新文件运行咖啡任务。 问题是这是一个同步过程,所以当另一个文件被改变(通常这发生在几毫秒内),然后Grunt Watch将不允许你运行另一个进程,直到debounceDelay已经到达。

默认的debounceDelay是500毫秒,但是这可以使用监视任务的选项来改变。 (阅读更多关于option.debounceDelay

基本上,当你保存多个文件,正如你所看到的 – 只有保存的第一个文件被改变。 为了绕过这一点,延迟(debouncing)函数运行的一个很好的工具是grunt.util ._。debounce这里是Lo-Dash链接)

该函数的参数是:

 _.debounce(func, wait, options) 

所以它需要在函数中,等待多less毫秒,以及一些选项(我们在这里不需要)。

当您调用debounce实用程序时,它将延迟waitTime函数的执行,并且以这种方式 – 当您一次保存多个文件时 – 在这200ms时间段之后,所有的调用将加起来一个函数调用。

这样 – 除了debounce util之外,这里最有用的一行是:

 changedFiles[filepath] = action; 

这将把文件添加到(最初)changedFiles的空对象。 请注意,在debounce函数启动后,我们重置changedFiles obj,以便下一个调用将只包含刚刚更改的文件。

令人惊叹的解决scheme确实;-)