Typically, a project will have grunt and its task libraries packaged in via NPM, and then configured in Gruntfile.js.
As it happens, Grunt is designed to be configured in a much more modular manner, via the
Using the following approach we can have a seperate .js file for each task (eg. run jshint, concatenate files, compile .sass to css, upload to S3) which we can then treat like plugins to our grunt system.
To maintain modularity, I try to keep project specific proprerties, such as paths and urls in a a seperate config in the project root.
For most items, I add them to the node package.json file, which is checked in to version control. For sensitive items, such db credentials, I use a config.json file (a throwback to the config.yml days) which is ignored by version control and partnered with config.sample.json, which gets checked in as an indication of what keys are expected by the system.
This is still a hurdle that new people on the project can trip over, so you’ll notice below I make a big song and dance in the logs when config.json is missing.
One thing I havent covered are compound-tasks, such as “watch these files and, when they change, lint the scripts, concat them and shoot them up to S3”. For that I just place a tasks.js file in with the others and define them like so:
If you’re like me, you’ll just want do download an example project with all this, so here it is, and here are some of my commonly used task files.
It took me a while to piece together this approach from different places, so if anyone has better ways of achieving these goals Id love to hear you approach (@linkthief).