How To Loop Through An Array And Run A Grunt Task Passing Each Value In The Array As A Grunt Option
Solution 1:
I think your problem is that your individual compile tasks are getting queued-up by grunt.task.run('compile');
, but, by the time they execute, your themes.forEach
loop has completed and your theme
option is set to the last value in themes
.
I think you will need to register a separate task that is responsible for setting the theme
option and running the compile task.
grunt.registerTask('compile_theme', function (theme) {
grunt.option('theme', theme);
grunt.task.run('compile');
});
You would enqueue this task within your compile:all
task for each of your themes:
themes.forEach(function(currentTheme) {
grunt.task.run('compile_theme:' + currentTheme);
});
If you want to be able to specify at the command-line which themes to compile, you would need to update your compile:all
task to read all --theme=
parameters and enforce that the value is an array:
grunt.registerTask('compile:all', function () {
var compileThemes = grunt.option('theme') || 'theme1';
if (grunt.util.kindOf(compileThemes) === 'string') {
compileThemes = [compileThemes];
}
compileThemes.forEach(function(currentTheme) {
grunt.task.run('compile_theme:' + currentTheme);
});
});
You would call the command as follows:
grunt compile:all // compiles 'theme1'
grunt compile:all --theme=theme2 // compiles 'theme2'
grunt compile:all --theme=theme2 --theme=theme3 // compiles 'theme2'and'theme3'
Note: You would probably want to rename your compile:all
task at this point because it no longer necessarily compiles all themes.
EDIT
It is not working because we are expecting too much of the theme
option. We are trying to use this to get the themes entered at the command-line and to compose values dynamically in our configuration (like, dest: theme + '/app.js'
. With the way I have structured my answer, theme
cannot be used in the configuration.
I would instead use a configuration variable for theme
that will be used in the config. This would mean updating the compile_theme
task:
grunt.registerTask('compile_theme', function(theme) {
grunt.config('theme', theme);
grunt.task.run('compile');
});
We would need to update our configuration by substituting template strings for theme
. For example:
dest:'<%= theme %>/app.js'
Solution 2:
Using for each never worked for me, but this did based off of this help doc from grunt: https://gruntjs.com/creating-tasks#multi-tasks
I added the list to my initConfig, ie
grunt.initConfig({
run_themes: {
theme1: 'sdi',
theme2: 'syd',
theme3: 'phl'
}});
Then:
//register task to loop through the themes
grunt.task.registerMultiTask('run_themes', 'Compile themes.', function() {
//grunt.themes.writeln(this.target + ': ' + this.data);
grunt.log.writeln(this.target + ': ' + this.data);
grunt.option('theme', this.data);
grunt.task.run('sass');
});
And my sass definition makes use of grunt.option('theme') like this to put a copy of the same compiled css in each theme directory like sdi/default/... syd/default... phl/default...
// compile our sass to css
sass: {
// sass compilation for "dev", unminified files
dev: {
options: {
style: 'expanded'
},
files: [{
expand: true,
cwd:'shared-resources/css/sass',
src: ['*.scss', 'standalone/*.scss'],
dest: "../<%= grunt.option('theme') %>/default/template-resources/css/dev",
ext: '.css'
}]
}},
Solution 3:
If you want to use the forEach
method to build out a series of tasks, push the tasks to a task array instead of running within the forEach
block:
grunt.registerTask('buildAll', function() {
var tasks = [];
themes.forEach(function(currentTheme) {
tasks.push('compile:' + currentTheme);
});
grunt.tasks.run(tasks);
});
Within your compile
task, you can pass currentTheme
to the task using this.args[0]
for normal tasks, or this.target
for multitasks:
grunt.registerTask('compile', function() {
var theme = this.args[0]; // sets local variable for use within task.
grunt.option('theme', this.args[0]); //sets option that can be referenced within this instance of `compile`
});
Post a Comment for "How To Loop Through An Array And Run A Grunt Task Passing Each Value In The Array As A Grunt Option"