codelord.net

Code, Angular, iOS and more by Aviv Ben-Yosef

Optimizing Angular Templates with Grunt on Heroku

| Comments

So it’s been a few months now of developing with AngularJS and we finally needed to do some optimizing. Specifically, we felt the need to bundle the dozens of separate HTML template files into a single file to save time on roundtrips to the server (especially with the latency heroku’s servers are showing in Israel).

Some googling showed that the best solution would be to use Grunt with grunt-angular-templates. Since we couldn’t easily find a complete example for Grunt newbies, I thought I’d share what we came up with. It might not be perfect, but it seems to work!

First we created a package.json file with the needed grunt dependencies and made sure to add a postinstall step that runs grunt. Turns out that heroku’s node buildpack runs that step after each deploy:

package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "name": "MyApp",
  "version": "0.1.0",
  "dependencies": {
    "grunt": "~0.4.1",
    "grunt-cli": "~0.1.9",
    "grunt-contrib-jshint": "~0.1.1",
    "grunt-contrib-nodeunit": "~0.1.2",
    "grunt-angular-templates": "~0.3.8"
  },
  "scripts": {
    "postinstall": "./node_modules/grunt-cli/bin/grunt"
  }
}

And then we just created a straightforward Gruntfile.js with the appropriate options for grunt-angular-templates specifying which files to bundle and where and the grunt boilerplate for telling it to run that task by default:

Gruntfile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    ngtemplates: {
        myapp: {
            options: {
                base: "web",
                module: "app",
            },
            src: "web/templates/**/*.html",
            dest: "web/js/templates.js"
        }
    }
  });

  // Load the plugin
  grunt.loadNpmTasks('grunt-angular-templates');

  // Default task
  grunt.registerTask('default', ['ngtemplates']);

};

And that’s it!

Also, if by any chance you, like us, don’t use Node for the server but still want to use the node buildpack for grunt’ing stuff for the client-side, and still need some stuff for the server buildpack, there’s a solution for you! There’s a buildpack called heroku-buildpack-multi that allows you to use multiple buildpacks for your project. Just switch your project to use it and then create a matching .buildpacks file. For example, for our Python tornado + Angular project it looks like:

.buildpacks
1
2
https://github.com/heroku/heroku-buildpack-python.git
https://github.com/heroku/heroku-buildpack-nodejs.git

Have fun! For more in-depth Angular stuff you might find this book useful.

Write maintainable Angular, learn the best practices and get prepared for 2.0!

Comments