I have an array similar to the following:
var themes = grunt.option('themes') || [
'theme1',
'theme2',
'theme3'
];
And another variable:
var theme = grunt.option('theme') || 'theme1';
This value is used in various places in my grunt file for things such as determining the path to some assets etc.
To cut a long story short, I run the following command to compile the assets for a single theme:
grunt compile --theme=theme2
I'm looking for a way to loop through the array of themes and run the compile
grunt task with the appropriate grunt.option. Essentially, what I'm looking to achieve would be the equivalent of this:
grunt compile --theme=theme1 && grunt compile --theme=theme2 && grunt compile --theme=theme3
I have tried the following:
grunt.registerTask('compile:all', function() {
themes.forEach(function(currentTheme) {
grunt.option('theme', currentTheme);
grunt.task.run('compile');
});
});
This runs the compile
task the appropriate number of times, but the theme
option doesn't seem to get set. So my Scss files get generated, but they are empty.
I've also tried this:
grunt.registerTask('compile:all', function() {
themes.forEach(function(currentTheme) {
grunt.util.spawn({
grunt : true,
args : ['compile', '--theme=' + currentTheme]
});
});
});
The task finishes almost instantly with a "success" message, but it doesn't appear to do anything.
The last thing I've tried is similar to the above, except I attempt to use async:
grunt.registerTask('compile:all', function() {
themes.forEach(function(currentTheme) {
var done = grunt.task.current.async();
grunt.util.spawn({
grunt : true,
args : ['compile', '--theme=' + currentTheme]
}, done);
});
});
But this task fails. I'm not really sure where I'm going wrong,
Thanks for any help
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 theforEach
block:Within your
compile
task, you can passcurrentTheme
to the task usingthis.args[0]
for normal tasks, orthis.target
for multitasks: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, yourthemes.forEach
loop has completed and yourtheme
option is set to the last value inthemes
.I think you will need to register a separate task that is responsible for setting the
theme
option and running the compile task.You would enqueue this task within your
compile:all
task for each of your themes: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:You would call the command as follows:
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 thecompile_theme
task:We would need to update our configuration by substituting template strings for
theme
. For example: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
Then:
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...