You can do Handlebars pre-compilation via the grunt-contrib-handlebars Grunt task. This task will pre-compile multiple templates into a single file.

The benefits from pre-compilation are:

  1. Only a single file is loaded by the client
  2. It will automatically organize your templates into a namespace
  3. Your templates are compiled once on the server instead of the browser

grunt-contrib-handlebars output

Say you have several templates located in the path /public/templates/ all ending with the .hbs extension:

/public/templates/home.hbs
/public/templates/login.hbs
/public/templates/create.hbs

You can use grunt-contrib-handlebars to convert these into a single output file

/public/templates/compiled.js

that you can reference on the client side. This task will take each template and create a corresponding function that will render the HTML for the template.

You can then use the pre-compiled Handlebars templates as so...

var homeHtml = mynamespace.home({});
// or
var loginHtml = mynamespace.login(user);

where mynamespace is the configured namespace and each function represents a template.

Using grunt-contrib-handlebars

So how do you go about doing pre-compiling Handlebars templates?

You will need to configure the task to have input files and an output file.

You can optionally specify a namespace to prefix your templates with.

Lastly, you can include a conversion function that will convert the filepath of each input template and convert it into a function name.

module.exports = function(grunt) {
  'use strict';

  // load grunt tasks
  grunt.loadNpmTasks('grunt-contrib-handlebars');

  // create configureation object
  grunt.initConfig({

    handlebars: {
      compile: {
        options: {
        
          // configure a namespace for your templates
          namespace: 'FistWallet.templates',

          // convert file path into a function name
          // in this example, I convert grab just the filename without the extension 
          processName: function(filePath) {
            var pieces = filePath.split('/');
            return pieces[pieces.length - 1].split('.')[0];
          }

        },
        
        // output file: input files
        files: {
          'public/templates/compiled.js': 'public/templates/*.hbs'
        }
      }
    }

  });

}

Using the output generated from the above is simply:

var html = FistWallet.templates.home({ some: data })
$("body").html(html);

For more configuration options, visit https://github.com/gruntjs/grunt-contrib-handlebars