My project has over 300 CoffeeScript files, so it takes several seconds to recompile everything. I\'d like to only recompile the changed CoffeeScript files.
Here\'s
I've had the same issue. I solved it using the regarde:file
event.
First I listen for changed files by using the regarde:file
event. This will feed the configuration for two tasks: clean:coffee
if files in the source location has been deleted and coffee:refresh
if files have been changed/added.
Then the regarde
task will trigger its tasks, which will launch refresh:coffee
(not to be mistaken from coffee:refresh
). This task will check if there is configuration added for clean:coffee
and/or for coffee:refresh
and run these tasks if needed (via function grunt.task.run
). If will also reset the flag, which will cause the next received regarde:file
event to cleanup the configuration again.
In depth explanation:
First of all, regarde
config:
// watch for changed coffeescript files
coffee: {
files: 'path/to/coffee/**/*.coffee',
tasks: ['refresh:coffee', 'livereload']
},
Then I listen for the regarde:file
event, where I update the clean:coffee
and coffee:refresh
file lists in their config.
Feed the configuration based on the regarde:file
event:
grunt.event.on('regarde:file', function (status, target, filepath) {
if (resetFlag) {
// clean file list from previous cycle, so clean clean:coffee and coffee:refresh
// file lists
...
resetFlag = false;
}
if (status === 'deleted') {
if (filepath) {
// calculate filepath's destination and
// add it to clean:coffee filelist
}
} else {
if (!grunt.file.isDir(filepath)) {
// add filepath to coffee:refresh filelist
}
}
}
It is easy to update configuration via grunt.config()
function. Below the code snippets to feed coffee:refresh
and clean:coffee
.
Adding config to coffee:refresh
:
var config = grunt.config('coffee') || {};
var value = config.refresh || {};
value.files = value.files || [];
...
var cwd = path.dirname(filepath),
src = path.basename(filepath),
dest = cwd.replace('path/to/source', 'path/to/dest');
value.files.push({
expand:true,
src:src,
dest:dest,
cwd:cwd,
ext:'.js'
});
grunt.config('coffee', config);
Adding config to clean:coffee
:
var cwd = path.dirname(filepath),
src = path.basename(filepath),
dest = cwd.replace('path/to/source', 'path/to/dest');
value.src.push(path.join(dest, src.replace('coffee', 'js')));
// clean only what has been removed
config = grunt.config('clean') || {};
config.coffee = value;
grunt.config('clean', config);
Task refresh:coffee
gets triggered:
grunt.registerMultiTask('refresh', 'refreshing the changed file(s)', function () {
this.requires('regarde');
var tasks = [];
var clean = grunt.config('clean');
// check if there is clean:refresh config available
if (clean && clean[this.target]) {
tasks.push('clean:' + this.target);
}
var config = grunt.config(this.target);
// check if there is coffee:refresh config available
if (config && config.refresh) {
tasks.push(this.target + ':refresh');
}
// run the tasks
grunt.task.run(tasks);
// set the resetFlag back to true
resetFlag = true;
});