在学习如何使用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');
};
这是使用grunt-coffee,基本上是这样的:https://gist.github.com/2373159。
当我运行grunt watch
并在test/cases/controller/*.coffee
中保存文件时,它会编译匹配文件的所有(将它们放在tmp/*
中)。< / p>
您如何使用grunt 仅编译已更改的文件?
答案 0 :(得分:15)
即将发布的(当前正在开发中)v0.4.0a grunt具有grunt.file.watchFiles对象,该对象专为此目的而设计。 grunt-coffee插件可能已经添加了对此功能的支持,我不确定。
无论哪种方式,如果您有兴趣在项目中尝试开发版本的grunt,请查看When will I be able to use in-development feature 'X'?常见问题解答条目。
答案 1 :(得分:8)
我在编译较少的文件时得到了这个功能。您应该能够使用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']);
};
答案 2 :(得分:4)
这些答案对我来说都不是很有效。如果有人有兴趣,这是我的解决方案(我知道我回答这个问题的时间有点迟了。)
答案 3 :(得分:3)
在此issue中,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
答案 4 :(得分:3)
https://github.com/tschaub/grunt-newer看起来完全符合类似的任务:
将Grunt任务配置为仅使用较新的文件运行。
概要:较新的任务将配置另一个与src一起运行的任务 a)比dest文件更新的文件或b)比last文件更新的文件 成功运行(如果没有dest文件)。请参阅下面的示例 还有更多细节。
您可以轻松地添加到任何任务中。在你的情况下:
grunt.loadNpmTasks('grunt-newer');
grunt.registerTask('default', 'newer:coffee');
答案 5 :(得分:2)
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('default',['myInitialBuild','watch']);
其中myInitialBuild
是初始构建(所有文件),然后在每个包上使用监视器跟进。实际上,您可以为每个文件执行此操作,但这听起来很糟糕。
答案 6 :(得分:2)
任务grunt-contrib-watch现在支持这一点。
https://npmjs.org/package/grunt-contrib-watch - &gt;寻找“根据需要编译文件”
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);
});
这可以防止任务在每次发生变化时编译所有文件。