Have Grunt generate index.html for different setups

I recently discovered these Grunt v0.4.0 compatible tasks:

  • grunt-preprocess

    Grunt task around preprocess npm module.

  • grunt-env

    Grunt task to automate environment configuration for future tasks.

Below are snippets from my Gruntfile.js.

ENV setup:

env : {

    options : {

        /* Shared Options Hash */
        //globalOption : 'foo'

    },

    dev: {

        NODE_ENV : 'DEVELOPMENT'

    },

    prod : {

        NODE_ENV : 'PRODUCTION'

    }

},

Preprocess:

preprocess : {

    dev : {

        src : './src/tmpl/index.html',
        dest : './dev/index.html'

    },

    prod : {

        src : './src/tmpl/index.html',
        dest : '../<%= pkg.version %>/<%= now %>/<%= ver %>/index.html',
        options : {

            context : {
                name : '<%= pkg.name %>',
                version : '<%= pkg.version %>',
                now : '<%= now %>',
                ver : '<%= ver %>'
            }

        }

    }

}

Tasks:

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

grunt.registerTask('dev', ['jshint', 'env:dev', 'clean:dev', 'preprocess:dev']);

grunt.registerTask('prod', ['jshint', 'env:prod', 'clean:prod', 'uglify:prod', 'cssmin:prod', 'copy:prod', 'preprocess:prod']);

And in the /src/tmpl/index.html template file (for example):

<!-- @if NODE_ENV == 'DEVELOPMENT' -->

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
    <script src="../src/js/foo1.js"></script>
    <script src="../src/js/foo2.js"></script>
    <script src="../src/js/jquery.blah.js"></script>
    <script src="../src/js/jquery.billy.js"></script>
    <script src="../src/js/jquery.jenkins.js"></script>

<!-- @endif -->

<!-- @if NODE_ENV == 'PRODUCTION' -->

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script src="http://cdn.foo.com/<!-- @echo name -->/<!-- @echo version -->/<!-- @echo now -->/<!-- @echo ver -->/js/<!-- @echo name -->.min.js"></script>

<!-- @endif -->

I’m sure my setup is different than most people, and the usefulness of the above will depend on your situation. For me, while it’s an awesome bit of code, the Yeoman grunt-usemin is a more robust than I personally need.

NOTE: I just discovered the above listed tasks today, so I might be missing a feature and/or my process may change down the road. For now, I’m loving the simplicity and features that grunt-preprocess and grunt-env have to offer. 🙂


Jan 2014 update:

Motivated by a down vote …

When I posted this answer there weren’t many options for Grunt 0.4.x that offered a solution that worked for my needs. Now, months later, I would guess that there are more options out there that could be better than what I have posted here. While I still personally use, and enjoy using, this technique for my builds, I ask that future readers take the time to read the other answers given and to research all the options. If you find a better solution, please post your answer here.

Feb 2014 update:

I’m not sure if it will be of any help to anyone, but I’ve created this demo repository on GitHub that shows a complete (and more complex setup) using the technique(s) I’ve outlined above.

Leave a Comment