Precompiled Handlebars templates in Backbone with

2019-03-15 00:41发布

问题:

I've been messing around with a backbone.js app using require.js and a handlebars templates (I've added the AMD module stuff to handlebars) and just read that pre-compiling the templates can speed it up a fair bit.

I was wondering how I would go about including the precompiled templates with requirejs. I have a fair few templates to compile (upwards of 15), so i'm not sure if they should all be in the same output file or have their own once compiled. Also, from what it seems, the compiled templates share the same Handlebars namespace that the renderer script uses, so I'm not sure how I would go about that when requiring the templates in my files.

Any advice would be awesome!

回答1:

Have a look at the Requirejs-Handlebarsjs plugin: https://github.com/SlexAxton/require-handlebars-plugin



回答2:

A simple approach is to create a RequireJS plugin based on the existing text! plugin. This will load and compile the template. RequireJs will cache and reuse the compiled template.

the plugin code:

// hbtemplate.js plugin for requirejs / text.js
// it loads and compiles Handlebars templates
define(['handlebars'],
function (Handlebars) {

    var loadResource = function (resourceName, parentRequire, callback, config) {
        parentRequire([("text!" + resourceName)],
            function (templateContent) {
                var template = Handlebars.compile(templateContent);
                callback(template);
            }
        );
    };

    return {
        load: loadResource
    };

});

configuration in main.js:

require.config({
    paths: {
        handlebars: 'libs/handlebars/handlebars',
        hb: 'libs/require/hbtemplate',
    }
});

usage in a backbone.marionette view:

define(['backbone', 'marionette',
        'hb!templates/bronnen/bronnen.filter.html',
        'hb!templates/bronnen/bronnen.layout.html'],
        function (Backbone, Marionette, FilterTemplate, LayoutTemplate) {
        ...

In case you use the great Backbone.Marionette framework you can override the default renderer so that it will bypass the builtin template loader (for loading/compiling/caching):

Marionette.Renderer = {
    render: function (template, data) {
        return template(data);
    }
};