Then I heard about handlebars.js and the precompilation feature won me over. This should speed loading times for the end users.
After playing with handlebars for a while, I wondered what’s the best way to integrate it into our web app development cycle. I googled, stackoverflowed, etc… but surprisingly, I couldn’t find decent information about the subject.
I opened my sketch-book and wrote a few goals for integrating handlebars:
- No build/compile step for development.
- Production code will use precompiled templates.
- No code changes required when switching from development to production.
Now that I knew what I was looking for, It was time to analyze handlebars behavior and write some code.
Compiling templates at runtime
This is suited for development, where raw templates are edited all the time.
The idea of precompiling templates is to eliminate step 2 from runtime. We do this by performing step 2 in an earlier build step called precompilation.
When you precompile a template, the raw template must reside in its own file with the .handlebars extension.
For this example, I created a file named hello.handlebars with the following conent:
Running the handlebars compiler from the terminal is easy:
handlebars hello.handlebars -f templates.js
Include the output script (templates.js) in the html file to get access to the templates. The templates are attached to the handlebars.templates object. Since my file was named hello.handlebars, it will set the compiled template as the value of the ‘hello’ key.
Here’s how to use it:
This is great for production code where templates aren’t changing at all.
The handlebars compiler can be used to compile multiple raw-template files into one templates.js file. Place all your .handlebars files in one folder (let’s name it templatesfolder) and issue the following command:
handlebars templatesfolder/ > templatesfolder/templates.js
So if you have hello.handlebars, goodbye.handlebars and you.handlebars in that folder, the output will be Handlebars.templates[‘goodbye’], Handlebars.templates[‘hello’] and Handlebars.templates[‘you’].
Mixing it together
How do we mix the development code with the production code?
We’ll create a wrapping method that returns the compiled version if it’s available. otherwise, it will fetch it (read the input of the raw template file), compile it and return it to the caller.
I call this function getTemplate and It’s going to be attached to the Handlebars object. Let’s see how the final code will use this function:
Let’s implement the getTemplate method in an empty templates.js file:
There are a few things to note here:
1. I used JQuery’s GET method in a synchronized way since the caller is expecting the template as the return value. This will somewhat degrade performance, but only in development mode. Since most developers use their own localhost for development, you should not feel any difference.
2. The use of jQuery’s GET requires that you host your site on a local server and not from disc (meaning: http:// is good, but file:// isn’t).
3. Once a template has been compiled at runtime, it will be added to the Handlebars.templates object (same way as the precompiled templates). The next time the template will be asked, the function will return it immediately.
Wrapping it up
So now that we have our getTemplate method residing in the templatesfolder/templates.js file, we need to precompile our templates and add them to the end of the templates.js file:
handlebars templatesfolder/ » templatesfolder/templates.js
The templates.js file now contains both the getTemplate method and all the compiled templates. When getTemplate is called, it will already have all templates compiled under Handlebars.templates and will not have to fetch/compile anything at runtime.
There are four steps in order to get handlebars working:
1. Include templates.js in your html after the handlebars.js script
2. Use getTemplate to get a compiled template.
3. Run the handlebars precompiler before delivering build to production.
A few more tips
1. You can optimize the templates with the compiler options:
handlebars <input> -f <output> -k each -k if -k unless
2. Since your templates are already precompiled, you can use the slimmer version of Handlebars (handlebars.runtime.js) on your production. It has a smaller footprint and will load faster.