Grunt Modules
Grunt Modules allows you to split up your grunt file into modular pieces. It's very useful for managing large codebases. We use it to manage the build system for a 400+ file application at Turn and it works like a charm.
In Grunt you define pieces of your modules within each multitask. Grunt Modules inverts the configuration so that you can have your module define it's tasks instead, allowing you to put entire cross-sections of your configuration in their own files.
Use
npm install grunt-modules
- Add
var gruntModules = require('grunt-modules');
to the top of your Gruntfile.js - Configure non-modular tasks in
grunt.initConfig({/* config */})
as usual - Include your modules via the
gruntModules(grunt, modules)
function.
var gruntModules = ;module{ grunt; ;}
For Example...
// Gruntfile.jsvar gruntModules = ;module { // A sample multitask which just echoes whatever // configuration object is given to it grunt; // Initialize the core config the standard way grunt; // Extend the core config with a grunt module ;};
// aModuleFile.js// A module defines a function which takes in the grunt object // and module name and returns a configuration object.module{ return // We can pass the multitask anything that the multitask // would accept for an individual task echo: "I'm in aModuleFile!" // will be transformed to echo:aModule };
// In the command line
$ grunt echo
Running "echo:inInitConfig" (echo) task
I'm in init config!
Running "echo:aModule" (echo) task
I'm in aModuleFile!
Grunt Modules takes the mapping between "aModule" and the function which produces the task map in "aModuleFile.js" and uses it to extend the grunt configuration. The end result is the same as if we had used this file:
// Gruntfile.jsmodule { grunt; grunt;
Modules
Modules are functions which take in a grunt object and the module name and return a configuration object. The configuration object should have multitask names as the keys, and a task configuration as the value.
// aModule.jsmodule{ return multiTaskName: /*task config*/ }
Multitasks don't behave as regular tasks in the module file configuration. For example if we had a module named "CaramelPopcorn":
// CaramelPopcorn.js// ... multiTaskName: src: 'popcorn' dest: 'caramel' // ...
It would have the same effect as if we had:
// Gruntfile.js// ... multiTaskName: CaramelPopcorn: src: 'popcorn' dest: 'caramel' // ...
If you want to create multiple tasks for a given multitask in a module, you can do so with the $
convention. For exmaple:
// aModule.js// ... multiTaskName: /*task config*/ multiTaskName$another: /*task config*/// ...
Would have the same effect as:
// Gruntfile.js// ... multiTaskName: aModule: {} aModule$another: {} // ...
Nested Modules
A module can nest other modules within itself. This is done by exporting an object instead of a function. When a module nests another module the . notation is used to define them in the Grunt configuration.
// aModule.jsmoduleexports = nestedModule: anotherNestedModule:
// Gruntfile.jsvar gruntModules = ;module { grunt; grunt; // Extend the core config with a grunt module ;};
The core above will produce a grunt configuration that behaves the same as:
// Gruntfile.jsmodule { grunt; // Extend the core config with a grunt module ;};