Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use precompiled templates in Handlebars with RequireJS?

I'd like to precompile my Handlebars templates, but I'm not sure how this works in development mode.

Is it common practice have some background process like Guard running to constantly monitor changes to Handlebars template files?

I'm using RequireJS to pull in templates; e.g.:

define(['jquery', 'handlebars', 'text!templates/my_template'], function($, Handlebars, myTemplate) {

  // ...

  var data = {"some": "data", "some_more": "data"};
  var templateFn = Handlebars.compile(myTemplate);
  $('#target').append(templateFn(data));

  // ...

});

So I understand once templates are precompiled, one would do this:

define(['jquery', 'handlebars'], function($, Handlebars) {

  // ...

  var data = {"some": "data", "some_more": "data"};
  var template = Handlebars.templates['my_template'];
  $('#target').append(template(data));

  // ...

});

Note the following about the in the second code snippet:

  1. The RequireJS module no longer pulls in the template.
  2. Handlebars.compile() is no longer used.

So typically would I have Guard running to keep my templates compiled whenever file system-level modifications happen to template files?

Basically my question is, is the intention for developers to do this?

if (development) {
  compile templates
}
else {
  use precompiled templates
}

I'm also using Rails, so maybe there is some black magic like sass-rails.

like image 898
Chad Johnson Avatar asked Aug 14 '13 16:08

Chad Johnson


2 Answers

Have you take a look at Require.js Handlebars Plugin (https://github.com/SlexAxton/require-handlebars-plugin) or epeli's requirejs-hbs (https://github.com/epeli/requirejs-hbs) ?

like image 58
Ian Lim Avatar answered Nov 02 '22 05:11

Ian Lim


Since asking this question, I've found that another way to achieve this might be via Grunt Watch. However, an even better way is to use Grunt and Browserify, skipping RequireJS altogether. Then you will be using NPM packages...and most of the libraries available with RequireJS seem to be available as NPM packages as well (amazingly even DOM-based libraries, like jQuery, Backbone, Angular). Then you use synchronous require() calls to require things:

var $ = require('jquery'),
    Backbone = require('backbone'),
    AppRouter = require('./app/routers/app');

// Compile LESS and attach resulting CSS to the HEAD.
require('./less/app.less');

$(function() {
    new AppRouter();
    Backbone.history.start();
});

This is much nicer, and it's possible because the app is fully built every time it runs. Combine this with Grunt Watch such that your app rebuilds itself every time there is a change, and you're in business.

And the build process even takes care of building Handlebars templates. To include a template, you would just do require('./templates/my-template.hbs'); and the build process for grunt-browserify will find this require() call, compile the template, and include the compiled template into the build app js file.

Much nicer than RequireJS!

like image 27
Chad Johnson Avatar answered Nov 02 '22 05:11

Chad Johnson