When we started using Grunt.js more heavily, it wasn't a problem for me that the main config file, Gruntfile.js just got larger and larger, until it reached ~500 LOC and got really nasty. At that point I realized we have to split it into smaller chunks somehow and here's how we did it.

First we created a folder grunt/config, and created a separate file for each tasks we have. Eg. grunt-md5's config is something similar to this:

Then, to keep DRY-ness of our config we created a tool in the grunt folder, available globally, making sure tasks can affect each other:

And then we updated each config in need such an update, again, config for grunt-md5 is now like:

Finally we changed Gruntfile.js to load the small lib we just created above and to load config for all the tasks too:

As a result Gruntfile.js is now only a few lines of code, all the tasks are configured by their own respective config file and still they can affect each other before they get to run.