Grunt tasks are very handy when it comes to frontend development, tooling some Node.js routines or even publishing your fresh new hipster blog.
Dynamic file object maps various
dest within one target.
But what about writing multiple targets at once — without add any line of code?
Some Grunt tasks may last too long and you don’t want to keep adding targets in your
Gruntfile.js. Here is a trick to expand targets automatically.
§The Initial Context
Mark McDonnell worked hard on making BBC News Sass compilation dynamic with Grunt.
He faced the problem of long Sass compilation time and wanted to split them in smaller chunks to reduce the time people stall during two changesets.
Hence the following file structure:
§Writing Targets Manually
If we wanted to be able to rebuild Sass files individually for each service, we would have to write the following code in our
This way, you type
grunt sass:afrique to compile only the BBC Afrique service stylesheets or
grunt sass:dist to rebuild all the services stylesheets — typically done only when releasing otherwise you will feel like living this comic strip.
You hence face 2 problems:
- the maintenance cost increases gradually as soon as new services requires to add new targets;
- the readability decreases as your Gruntfile get more and more bloated by repetitive content.
Mark’s technique has been great at removing this pain — and he even improved it to leverage the Grunt Config API): he dynamically generated the Grunt targets on runtime.
I’ve been working at making BBC News Grunt tooling battle-tested and pluggable into their CI process. It gave me the opportunity to simplify things.
Because I had time and found it challenging.
§Enters Grunt Property Expand
grunt.template mechanism is recommended to avoid repetitions, and to reuse configuration values.
Templates are evaluated on runtime, when a task is duely queued and ran. Not when
grunt.initConfig is called.
Which means we have access to the
In the case of
sass and then, its arguments:
grunt.task.current.args is an array for which the first index equals
We don’t need to know more, we can define a static target and provide a complementary argument which will route the services properly like this:
Gruntfile.js will never grow in size or require any new line of code to target a sub-tree of our codebase:
§The Bay Watcher
We can apply the same sugar to the
watch task to recompile automatically our Sass files.
Still, we don’t want to rebuild the whole files assets. We only want to recompile service’s modified Sass files.
This is doable by applying the same technique, not only in the
src target configuration, but also in the
While writing this blogpost, I discovered a sentence in the Inside Grunt Tasks page documentation:
While a task is running, Grunt exposes many task-specific utility properties and methods inside the task function via the this object. This same object is also exposed as grunt.task.current for use in templates.
Some would say RTFM.
I would say it was worth finding and learning it.