npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

load-grunt-configs

v1.0.0

Published

Loads grunt task configurations from separate files

Downloads

13,206

Readme

load-grunt-configs

npm version Build Status

Loads grunt task configurations from separate files.

Grunt files tend to grow fast due to big amount of tasks and their configuration objects. This module allows you to split your Grunt task configuration objects into separate files any way you choose. There are similar modules that allow you to the same, but with grunt-load-configs you can configure targets for a single task in multiple files.

This means you no longer need to group all task targets into a single file, but can split them up according to their task dependencies.

Example

you use the watch task to recompile your .scss files, but also to lint your source .js whenever one has changed. Typically you'd add a single watch configuration object to configure this, but with load-grunt-configs you can split these into several files and group all task targets together whenever it makes sense:


//config/css.js

module.exports.tasks = {
    watch : {
        scss : {
            files : ['app/sass/*.{scss,sass}'],
            tasks : ['compass:source']
        }
    },
    compass : {
        source : {
            //configuration settings
        }
    }
};

//config/lint.js

module.exports.tasks = {
    watch : {
        lint : {
            files : ['app/{,*/}*.js']
            tasks : ['jshint:source']
        }
    },
    jshint : {
        source : {
            //configuration settings
        }
    }
}

Getting Started

load-grunt-configs supports the loading of grunt config files in following formats:

  • json
  • js modules
  • coffee modules
  • cson
  • yaml

Though the provided examples are mainly for json files and js modules, the same applies to the other formats. You can find examples of all formats in the config directory of this project.

Migrating your configuration from a big, fat grunt file

I wrote a small utility Grunt task which takes your full-blown Grunt configuration and automatically splits it into separate files: grunt-generate-configs (supports all formats load-grunt-configs does too)

You only need to do this once:

$ npm install grunt-generate-configs -g
# cd to your project directory containing the Gruntfile
$ generate_configs

This will create a separate .json file for each task inside a config directory. (See grunt-generate-configs for all options: a different format, directory, etc.)

Next you need to delete the full configuration object in your Gruntfile.js.

Then ...

Automatically loading the config files

Install the load-grunt-configs module with: npm install load-grunt-configs --save-dev

// Gruntfile.js
module.exports = function (grunt) {
    grunt.loadNpmTasks('grunt-contrib-jshint');

    //loads the various task configuration files
    var configs = require('load-grunt-configs')(grunt);
    grunt.initConfig(configs);

    grunt.registerTask('default', ['jshint']);
}

load-grunt-configs supports the loading of config files as .js, .json, .yaml or .coffee. You can even mix and match if you want. Take a look at the config folder of this project to see examples for all formats.

To configure the jshint task for example, add a file config/jshint.json (in case you didn't use the generator to automatically generate it):

{
    "gruntfile" : {
        "src" : "Gruntfile.js"
    }
}

By default the basename (without the file extension) of the filename will be used to recognize which task is being configured. jshint in the above example.

Advanced usage

Using node modules for configuration

Task configuration is also possible through node modules, either by exposing an object:

//config/jshint.js
module.exports = {
     gruntfile : {
         src : "Gruntfile.js"
     }
 }

Or by exposing a function which returns an object:

//config/jshint.js
module.exports = function(grunt, options) {
     return {
         gruntfile : {
             src : "Gruntfile.js"
         }
     }
 }

Declaring multiple task configurations in one file

If the returned object contains a tasks key, its value will be assumed to be a name/configuration pair mapping:

//config/grunt.json
{
    "tasks" : {
        "jshint" : {
            "gruntfile" : {
                "src" : "Gruntfile.js"
            }
        },
        "watch"  : {
            "gruntfile" : {
                "src" : "Gruntfile.js",
                "tasks" : ['jshint:gruntfile']
            }
        }
    }
}

The above will configure both the jshint and watch tasks.

Split multi-task configurations

But wait, there is more! You can split multi-task configurations in multiple files as well. For instance if you have the above config/grunt.json file and you add the following file:

//config/test.json
{
    "tasks" : {
        "jshint" : {
            "test" : {
                "src" : ["test/**/*.js"]
            }
        }
        "watch" : {
            "test" : {
                "src" : ["test/**/*.js"],
                "tasks" : ['jshint:test']
            }
        }
    }
}

Now both watch and jshint tasks have two targets: gruntfile and test.

Passing values to the configuration files

If you declare a function in your config file it receives two arguments: grunt and options, which allows you to use the grunt instance and pass values. In this way, you can declare custom tasks on your config files (especially useful if you follow the "Split multi-task configurations" method above).

// Gruntfile.js
var options = {
    paths : {
        jshintrc : '.jshintrc'
    }
};

var configs = require('load-grunt-configs')(grunt, options);

// config/jshint.js
module.exports = function(grunt, options) {
    grunt.registerTask('custom', ['jshint:gruntfile']);

    return {
        options : {
            jshintrc : '<%= paths.jshintrc %>'
        },

        gruntfile : {
            src : 'Gruntfile.js'
        }
    };
}

Task name prefixed task targets

As a convenience method you can prefix your task targets with the task name, separated by a ":" (colon). This allows you to do this:

//config/monitor.js
module.exports.tasks = {
    "watch:test" : {
        src : ["test/**/*.js"],
        tasks : ['jshint:test']
    },
    "watch:gruntfile" : {
        src : "Gruntfile.js",
        tasks : ['jshint:gruntfile']
    }
}

This makes it easier when in the future you'd like to move the watch:gruntfile task configuration to another file for instance.

Troubleshooting

The tradeoff of a neatly organized Grunt configuration is sometimes having trouble locating which file is declaring exactly what.

In that case, or if loading some file is causing an error and aborting your Grunt process, you can always run:

grunt --verbose

A nice log of processed files and loaded tasks/targets will help you locate the problems. Here's the output when running on this very repo:

Loading grunt configs via "load-grunt-configs" from 6 file(s).
Loading config/connect.js...is fn(), invoking...OK
+ connect: [options, docs]

Loading config/jshint.json...OK
+ jshint: [options, lib, build, test]

Loading config/watch.js...is fn(), invoking...OK
+ watch: [lib, build, test, docs, livereload]

Loading config/clean.coffee...is fn(), invoking...OK
+ clean: [config, tmp]

Loading config/nodeunit.yml...OK
+ nodeunit: [load_grunt_configs]

Loading config/markdown.cson...OK
+ markdown: [docs]

Options

You can modify the directory in which the configuration files need to reside:

//Gruntfile.js
var options = {
    config : {
        src : "options/*.js"
    }
};

configs = require('load-grunt-configs')(grunt, options);

Will search for the configuration files in an options directory.

You can also supply a customizer function for the configuration merging:

//Gruntfile.js
var options = {
    config : {
        mergeCustomizer : function(a, b) {
            return Array.isArray(a) ? a.concat(b) : undefined;
        }
    }
};

configs = require('load-grunt-configs')(grunt, options);

See lodash#merge for more information on the customizer function.

Examples

You can take a look at the Gruntfile.js and the configuration files in the config directory of this project. Or browse through the 3 demos in this repository:

  1. Configuration per task. Each task configuration goes into its own file: watch.js, jshint.js, concurrent.js, ...
  2. A single configs file. The entirety of the grunt configuration is moved to a seperate file (grunt.js). This way the Gruntfile.js only contains task declarations.
  3. Configuration by task type. Task target configurationsare spread over multiple files and grouped wherever logically it makes sense. E.g. build.js, serve.js, test.js
  4. Various formats: See the config directory of this project.

All various possibilities

  • json with a single task configuration: E.g. configures jshint task in config/jshint.json (task name extracted from file name)
{
    "gruntfile" : {
        "src" : "Gruntfile.js"
    }
}
  • json with multiple task configurations: E.g. configures jshint and watch tasks in config/<whatever makes sense to you>.json. Note the top-most key "tasks" here, it alerts the module not to extract the task name from the file name.
{
    "tasks" : {
        "jshint" : {
            "gruntfile" : {
                "src" : "Gruntfile.js"
            }
        },
        "watch" : {
            "gruntfile" : {
                "src" : "Gruntfile.js",
                "tasks" : ["jshint:gruntfile"]
            }
        }
    }
}
  • json with multiple task configurations using task prefixed targets: E.g. configures jshint and watch tasks in config/<whatever makes sense to you>.json
{
    "tasks" : {
        "jshint:gruntfile" : {
            "src" : "Gruntfile.js"
        },
        "watch:gruntfile" : {
            "src" : "Gruntfile.js",
            "tasks" : ["jshint:gruntfile"]
        }
    }
}
  • js with single task configuration as an object: E.g. configures jshint task in config/jshint.js
module.exports = {
     gruntfile : {
         src : "Gruntfile.js"
     }
};
  • js with single task configuration as a function: E.g. configures jshint task in config/jshint.js
module.exports = function(grunt, options) {
    return {
        gruntfile : {
            src : "Gruntfile.js"
        }
    };
};
  • js with multiple task configurations as an object: E.g. configures jshint and watch task in config/<whatever makes sense to you>.js
module.exports.tasks = { //note the `tasks` export here [!]
    jshint : {
        gruntfile : {
            src : "Gruntfile.js"
        }
    },
    watch : {
        gruntfile : {
            src : "Gruntfile.js",
            tasks : ['jshint:gruntfile']
        }
    }

};
  • js with multiple task configurations as a function: E.g. configures jshint and watch task in config/<whatever makes sense to you>.js
module.exports = function(grunt, options) {
    return {
        tasks : {
            jshint : {
                gruntfile : {
                    src : "Gruntfile.js"
                }
            },
            watch : {
                gruntfile : {
                    src : "Gruntfile.js",
                    tasks : ['jshint:gruntfile']
                }
            }
        }
    };
};
  • js with multiple task configurations as an object using task prefixed targets: E.g. configures jshint and watch task in config/<whatever makes sense to you>.js
module.exports.tasks = { //note the `tasks` export here [!]
    "jshint:gruntfile" : {
        src : "Gruntfile.js"
    },
    "watch:gruntfile" : {
            src : "Gruntfile.js",
            tasks : ['jshint:gruntfile']
    }
};
  • js with multiple task configurations as a function using task prefixed targets: E.g. configures jshint and watch task in config/<whatever makes sense to you>.js
module.exports = function(grunt, options) {
    return {
        tasks : {
            "jshint:gruntfile" : {
                src : "Gruntfile.js"
            },
            "watch:gruntfile" : {
                src : "Gruntfile.js",
                tasks : ['jshint:gruntfile']
            }
        }
    };
};

Changelog

  • v0.4.3:
    • Update dependencies
    • Swap cson-safe to cson-parser
    • add mergeCustomizer
  • v0.4.2: Explicit bailing on invalid task config
  • v0.4.1: Better verbose output
  • v0.4.0: Switch to cson-safe for parsing cson
  • v0.3.3:
    • Add cson support
    • Loads yaml files with safeLoad
  • v0.3.2:
    • fixes incorrect grunt dep
    • adds coffee config file
    • adds yaml support
  • v0.3.1:
    • fixes incorrect overwrite of passedin options for this task
    • adds tests
    • Updates examples and adds all various configuration possibilities
  • v0.3.0:
    • disallows function declaration anywhere else than as direct export
    • extracts taskname regardless of file extension
  • v0.2.0:
    • adds coffeescript support
    • adds parsing of taskname prefixed task targets
    • fixes incorrect handling of functions at task config leaves
  • v0.1.0:
    • adds "by type' demo
    • adds "by taskname" demo
    • adds "single file" demo
    • Initial commit

Contributors

License

Copyright (c) 2014 Camille Reynders Licensed under the MIT license.

With special thanks to @stefanpenner and @thomasboyt. This module is based on the ideas in Thomas' excellent tutorial: http://www.thomasboyt.com/2013/09/01/maintainable-grunt.html

Analytics