Configuring Connection URLs With Grunt

Written by

A recent AngularJS application I wrote had to be configured based on a query string. Grunt launches the application in a browser using grunt-contrib-connect offering various options e.g. port, protocol and hostname. However, there is no out the box solution for appending query strings that I am aware of. It’s a minor addition to my development workflow, but manually adding the query string to the url once Grunt launches the browser started to become an irritation. Here is a simple solution I found that worked.

Quickest solution

Within the Gruntfile, find the open property within connect and append your query string to the server url:

open: {
  server: {
    url: 'http://localhost:<%= connect.options.port %>?foo=bar'
  }
}

If you now run grunt server you’ll see it now loads the url appending the query string.

Configuration file solution

I quickly realised using Grunt that there were certain configuration properties I wanted to use e.g. environment config vars from a project file or environment variables (see Heroku). Seperating these configuration properties also ensured inadvertantly overly bloating the Gruntfile. What this also meant is I could remove the hard coded query string value from the Gruntfile and use configuration properties within an external file (much nicer).

Create a configuration object

Above the initConfig method within the Gruntfile create a new object named devConfig and add an env property:

var devConfig = {
    env: '...' // Todo: populate from a file
};

Load configuration data

For this example we will load JSON data from a file within the project itself.

  1. Create a file named environment.json within a directory named config at the project root.

    mkdir -p config;touch config/environment.json

  2. Add the following to the environment.json file:

     {
         "dev": {
             "foo": "bar"
         }
     }
    
  3. Using grunt.file you can read a JSON file in addition to other file formats such as YML. Back in the Gruntfile, using readJSON load the configuration JSON and assign it to the env property:

     var devConfig = {
         env: grunt.file.readJSON('./config/environment.json')
     };
    
  4. Assign the devConfig object to a devconfig property on the grunt configuration object within the initConfig method.

     grunt.initConfig({
         yeoman: yeomanConfig,
         devconfig: devConfig,
         watch: {
           coffee: {
             files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
             tasks: ['coffee:dist']
           }...
    
  5. Find the open property within connect and append your query string to the server url and use the devconfig object to assign the correct property:

     open: {
       server: {
         url: 'http://localhost:<%= connect.options.port %>?foo=<%= devconfig.env.dev.foo %>'
       }
     }
    

If you now run grunt server you will see it will still load the url and append the query string, this time from the JSON file.

Configuration file alternatives

You need not rely on a JSON file as in this example, you could alternatively use a .env file as detailed in this Heroku post and read the file using readYML. You could also load your current environment variables using the following:

var devConfig = {
    env: process.env
};

Further reading

@thomasaboyt wrote a great article well worth reading: Maintainable Grunt

Comments