If you find that the "directory-only" behavior of grunt.loadTask() annoying (that is, it wants to keep the definitions of external tasks next to the configuration of external tasks), you can try something like this:
module.exports = function(grunt) { var env = process.env.NODE_ENV || 'dev'; var _ = require('lodash'); /*** External config & tasks filepaths ***/ //we have 1 base config, and possibly many module-specific config var configLocations = ['./grunt-config/default_config.js', './grunt-config/**/config.js']; //we have 1 base tasks definition, and possibly many module-specific config var tasksLocations = ['./grunt-config/default_tasks.js', './grunt-config/**/tasks.js']; /* Typical project layout (matching with the globbing pattern above - adapt to your project structure) : βββ Gruntfile.js βββ package.json βββ grunt-config β βββ homepage β β βββ config.js β βββ navigation β β βββ config.js β βββ module1 β β βββ config.js β β βββ tasks.js β βββ default_config.js β βββ default_tasks.js β βββ template_module_grunt.txt βββ website_directory1 β βββ mdp β βββ multimedia-storage β βββ mv-commit.sh β βββ query β βββ temp β βββ tmp βββ website_directory2 βββ crossdomain.xml βββ css βββ favicon.ico βββ fonts : : : */ /***************** External configuration management ***********************************/ var configFiles = grunt.file.expand({ filter: "isFile" }, configLocations ); grunt.log.writeln('Gathering external configuration files'.underline.green); grunt.log.writeln("configFiles : " + grunt.log.wordlist(configFiles, { separator: ', ', color: 'cyan' })); var configArray = configFiles.map(function(file) { grunt.log.writeln("=> importing : " + file); return require(file)(grunt, env); }); var config = {}; configArray.forEach(function(element) { config = _.merge(config, element); }); grunt.initConfig(config); /***************** Task loading & registering *******************************************/ // We load grunt tasks listed in package.json file require('load-grunt-tasks')(grunt); /****** External tasks registering ****************/ grunt.log.writeln('Gathering external task files'.underline.green); var taskFiles = grunt.file.expand({ filter: "isFile" }, tasksLocations); grunt.log.writeln("task files : " + grunt.log.wordlist(taskFiles, { separator: ', ', color: 'cyan' })); taskFiles.forEach(function(path) { grunt.log.writeln("=> loading & registering : " + path); require(path)(grunt); }); grunt.registerTask('default', ['jshint:gruntfile', 'logConfig']); grunt.registerTask('checkGruntFile', 'Default task - check the gruntfile', function() { grunt.log.subhead('* TΓ’che par dΓ©faut - aide et vΓ©rification du gruntfile *'); grunt.log.writeln('ExΓ©cutez "grunt -h" pour avoir plus d\'informations sur les tΓ’ches disponibles'); grunt.log.writeln('...'); grunt.log.subhead('VΓ©rification du gruntfile...'); grunt.task.run(['jshint:gruntfile']); }); //write the generated configuration (for debug) grunt.registerTask('logConfig', 'Write the generated conf', function() { //grunt.task.run(['attention:gruntfile']); grunt.log.subhead('* Configuration gΓ©nΓ©rΓ©e : *'); grunt.log.writeln(JSON.stringify(config, undefined, 2)); }); };
Source: https://gist.github.com/0gust1/7683132
source share