Compass compiles the stylesheets and JSHint checks the scripts, and both are run by hand until somebody forgets. grunt-contrib-watch is the piece that makes a task runner worth installing: it holds the file globs and runs the right task when the right file changes.
module.exports = function (grunt) {
grunt.initConfig({
compass: { dev: { options: { sassDir: 'src/scss', cssDir: 'public/css' } } },
jshint: { all: ['src/js/**/*.js'] },
watch: {
css: { files: 'src/scss/**/*.scss', tasks: ['compass:dev'] },
js: { files: 'src/js/**/*.js', tasks: ['jshint'] },
options: { livereload: true }
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('default', ['compass:dev', 'jshint']);
};
Two details decide whether it stays installed. Separate watch targets, so editing a stylesheet does not also lint the whole script tree — one catch-all target turns a 200ms compile into a four-second pause on every save, and people stop saving. And livereload: true with the browser extension removes the refresh, which sounds trivial until the page being styled takes six clicks to get back into. The cost is that Grunt spawns a new process per run by default, which is where most of the delay is; spawn: false is noticeably faster and means a task that throws takes the watcher down with it, so the terminal has to be visible.