Warning: Creating default object from empty value in /homepages/39/d161420129/htdocs/p373.net/wp/wp-content/themes/p373b/admin/functions.php on line 183
How to create environment based builds with Grunt

How to create environment based builds with Grunt

Grunt is pretty neat when it comes to creating builds of javascript applications.  However, I found it quite difficult to create environment based builds, ie, builds for development, staging, and production.

First off, let me say that I’m not a javascript developer.  In reality, what I”m trying to do is very simple: create a deployment pattern for a Google Chrome extension.  The idea is that I want to be able to specify environment configuration variables such as endpoint and build directory so I can point different builds to different directories and have their api clients talk to different endpoints.

Let’s start with getting a chrome extension to build to different directories depending on which Grunt build task I execute.

First, you need to install grunt-env(You should probably already have Grunt installed).  Start by following the usual instructions here: https://github.com/jsoverson/grunt-env

To be nice, I’ll be explicit as well:

// You want the --save-dev so it updates your package.json file
npm install grunt-env --save-dev

At the bottom of your Gruntfile:

grunt.loadNpmTasks('grunt-env');

In your grunt.initConfig({…}) block, enter:

  env : {
    options : {
    //Shared Options Hash
    },
    dev : {
      NODE_ENV : 'development',
      DEST     : 'builds/dev'
    },
    build : {
      NODE_ENV : 'production',
      DEST     : 'builds/production'
    }
  }

If you look at the README for the grunt-env project, you’ll notice I”ve gone away from what they have.  It baffles my mind that its the convention to have a “dist” directory at the top level of a project, as opposed to have a builds directory where you can have any number and types of builds.  So thats why I’ve put DEST: “builds/production”.

Grunt now gives us tasks to specify which environment we want, like so:

grunt.registerTask('dev', ['env:dev', 'build']);

This is all gravy, but how do you take advantage of your environment configuration variables?

This took me forever to figure out, but alas, that’s why I’m writing this blog post, and you, dear reader, are reading it :)

Ok, so there are two ways you might want to access these variables:

  1. 1. In a task
  2. 2. In a template in the configuration

1. Accessing environment configuration in a task is straightforward, as long as you combed through the source code and figured it out, or read below:

process.env.DEST

2. Accessing from within a template

You might think, you could just do:

grunt.initConfig({
  chromeManifest: {
    dist: {
      dest: '<% process.env.DEST%>'
    }
  } 
})

But you’d be wrong!  Templates are executed in the context of the configuration, so you don’t have access to process.  What you need to do, is set a configuration var inside a task that has access to process.  Here’s the special sauce:

grunt.registerTask('setenv', 'Override all grunt build options with environment specific options', function() {

grunt.config('BUILD_ENV', process.env.ENV)

});

And then in the template:

dest: '<%= env[BUILD_ENV].DEST %>'

Boom! environment based configuration for dinner. delicious.

In part 2 of adventures in Grunt-land, I’m going to go over how to update a Google Chrome extension manifest file with an environment configuration file

    This entry was posted in Coding, Ruby/Rails, Technology and tagged , , . Bookmark the permalink. Both comments and trackbacks are currently closed.