How to run two grunt watch tasks simultaneously
Is it possible to run two watch tasks simultaneously?
I understand that I can have any number of tasks I want inside watch settings and just launch grunt watch and it will watch all of them, like this
...
watch: {
A: {
files: "js/dev/**/*.coffee",
tasks: ["coffee", "requirejs"]
},
B: {
files: "js/dev/**/*.coffee",
tasks: ["coffee"]
},
C: {
files: "js/dev/**/*.html",
tasks: ["copy"]
}
}
...
...but I don't need this. I just want to have different set of tasks for development and production. As you can guess, the only difference between A (production) and B (development) is minification and concatenation. I don't need to launch A and B tasks at the same time.
First I came with this idea
grunt.registerTask("prod", ["watch:A", "watch:C"]);
grunt.registerTask("dev", ["watch:B", "watch:C"]);
But this didn't work. Just first watch tasks is working (C never works). Is that possible to do what I want?
Solution 1:
I've found using grunt-concurrent works:
concurrent: {
options: {
logConcurrentOutput: true
},
prod: {
tasks: ["watch:A", "watch:C"]
},
dev: {
tasks: ["watch:B", "watch:C"]
}
}
Then:
grunt.registerTask("prod", ["concurrent:prod"]);
grunt.registerTask("dev", ["concurrent:dev"]);
Solution 2:
EDIT: concurrent now has a logConcurrentOutput
option! More info here: https://github.com/sindresorhus/grunt-concurrent#logconcurrentoutput.
Watch is a weirdly concurrent but blocking task, so you have to be creative to get multitask-like functionality working.
Concurrent loses all output from the watch tasks, which isn't ideal.
Try dynamically writing the config object in a custom task:
grunt.registerTask('watch:test', function() {
// Configuration for watch:test tasks.
var config = {
options: {
interrupt: true
},
unit: {
files: [
'test/unit/**/*.spec.coffee'
],
tasks: ['karma:unit']
},
integration: {
files: [
'test/integration/**/*.rb',
'.tmp/scripts/**/*.js'
],
tasks: ['exec:rspec']
}
};
grunt.config('watch', config);
grunt.task.run('watch');
});
Solution 3:
The best and only working solution is there : https://npmjs.org/package/grunt-focus Add this plugin and then :
focus: {
sources: {
include: ['js', 'html', 'css', 'grunt']
},
testu: {
include: ['js', 'html', 'css', 'testu', 'grunt']
},
testi: {
include: ['js', 'html', 'css', 'testu', 'testi', 'grunt']
}
},
watch: {
js: {
files: paths.js,
tasks: ['jshint'],
options: {
livereload: true
}
},
html: {
files: paths.html,
options: {
livereload: true
}
},
css: {
files: paths.css,
tasks: ['csslint'],
options: {
livereload: true
}
},
testu: {
files: ['test/**/*.js', 'test/**/*.css'],
tasks: ['mochaTest'],
options: {}
},
testi: {
files: ['test/**/*.js', 'test/**/*.css'],
tasks: ['exec:cleanTestDB', 'protractor_webdriver', 'protractor'],
options: {}
},
grunt: {
files: ['Gruntfile.js', 'server/config/env/*.js'],
options: {
reload: true
}
}
}
Then you use focus:sources or focus:testu as your convenience.
JM.