Quick Handlebars tip concerning precompilation

This post is more than 2 years old.

So, I'm not sure I can say why I'm playing with Handlebars today (just asked if I could talk about it), but I ran into an interesting issue with it today that I thought I'd share.

Handlebars supports precompilation of templates. This makes your application run a bit quicker by skipping the template compilation phase. It's done via a simple CLI program you can install via npm.

Handlebars also supports partials. These are templates that are meant to be included in other templates. Oddly, the Handlebars site doesn't document this feature. (To be clear, it mentions the API for it, but doesn't describe it as a feature.) If you go to the Github repo for Handlebars though it is fully documented.

Ok, so the normal way to compile templates is like so:

handlebars file.handlebars file2.handlebars -f templates.js

This takes two files, file.handlebars and file2.handlebars, and compiles it into one file, templates.js. Once you've done that, and included the file, you can access the template function like so:

rendered = Handlebars.templates.file(data here);

The file name, minus the extension, becomes the name of the template function. As an FYI, you should name your files with the .handlebars extension. If you don't, then the full file name becomes the name of the template function. If I had used file.html as my filename, then my template function would be file.html, and who knows what grief that dot would have caused.

Ok, so to handle partials, you have to pass a flag, -p:

handlebars mypartial.handlebars -p -f partials.js

As before, the name of the file dictates how you would use it. If I had used the file name from the code snippet above, I could include a partial like so: {{> mypartial}}. As before, ensure you use the handlebars file extension. I had used .partial to help keep things organized and ran into the issue with the name being mypartial.partial instead of just mypartial.

Ok, so finally, the tip. As far as I know, there is no way to compile 'regular' templates and partials in one call. So to create my compiled templates and partials and store them in one file, I've ended up doing this:

handlebars file1.handlebars file2.handlebars file3.handlebars -f templates.js
handelbars file10.handlebars file11.handlers -p -f partials.js
cat templates.js partials.js > templates_all.js

The handlebars CLI supports globs which means I could have used *.handlebars, but since I had my templates and partials in one folder, that wouldn't have worked. And obviously you could automate this with a simple Grunt script as well.

It is certainly possible that I'm wrong about the need to do this in multiple calls. I opened a ticket over on the Handlebars site to request this feature and if I'm missing the obvious, I'll update the blog entry. (And part of me hopes that I'm wrong and this entire blog entry is a waste. :)

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Raymond Camden posted on 3/16/2015 at 3:55 PM

As an FYI, the project creator already said no to my ticket, so, this post is useful I guess.

Comment 2 by Free Bird posted on 12/2/2015 at 7:12 AM

Thanks for writing such information.. That's exactly what I was looking for!

Comment 3 by Naresh Sharma posted on 3/21/2016 at 12:07 PM

Nice Article!!. could you please let me know to register precompiled partials. I try like Handlebars.registerPartial("partialname", 'partial.js'). But not working.

Comment 4 (In reply to #3) by Raymond Camden posted on 3/21/2016 at 1:37 PM

What if you drop the .js?

Comment 5 (In reply to #4) by Naresh Sharma posted on 3/21/2016 at 5:11 PM

This really solves my problem. Thanks a lot Raymond.
Handlebars.registerPartial("partialName", Handlebars.partials['partial']);

Comment 6 by Joel posted on 4/13/2016 at 9:35 PM

Thank you for posting this! This saved me a lot of hair-tearing. I made an npm script to automate this precompilation process, which all in all has made my first Handlebars experience much more pleasant than it was starting to become.

Comment 7 (In reply to #6) by Raymond Camden posted on 4/14/2016 at 1:27 PM

You are most welcome.

Comment 8 by Scheffler posted on 1/11/2017 at 3:19 PM

Thx for the article.
I have a question, how precompilation can work with partials? Do you have try once?
I try to find a way to make it works but when you put the partial syntax into your main template, you can't compile anymore..

Thx for the answer!

Comment 9 (In reply to #8) by Raymond Camden posted on 1/11/2017 at 7:36 PM

I describe how to work with them in the post above. Did you see it?

Comment 10 (In reply to #9) by Scheffler posted on 1/11/2017 at 7:46 PM

Yes i see it, but it doesn't work when I try it.. Then i found a solution.
Thx for the answer Raymond !

Comment 11 (In reply to #10) by Raymond Camden posted on 1/11/2017 at 7:59 PM

Cool - so is it something i got wrong, or did it change in Handlebars? (This blog entry is almost two years old.)

Comment 12 (In reply to #11) by Scheffler posted on 1/12/2017 at 12:17 PM

No everything you say is right! In fact, I had another error in my template which crash my compilation but it was on exact same place of my partial declaration.
So I thought it was my partial ^^
Thx for your article, very helpful!

Comment 13 (In reply to #12) by Raymond Camden posted on 1/12/2017 at 3:07 PM

Glad to hear it. As an FYI, I have a book, and video series, on client-side templating. You can buy it via the "About" link above. Or not. It's all good. ;)