Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Closure compiler with Underscore.js _.template

Is there any way to compile Underscore.js templates on the server and get the Closure compiler to work with the generated code?

The main problem is that _.template:

_.template = function(str, data) {
    var c  = _.templateSettings;
    var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
        'with(obj||{}){__p.push(\'' +
        str.replace(/\\/g, '\\\\')
        .replace(/'/g, "\\'")
        .replace(c.interpolate, function(match, code) {
            return "'," + code.replace(/\\'/g, "'") + ",'";
        })
        .replace(c.evaluate || null, function(match, code) {
            return "');" + code.replace(/\\'/g, "'")
                .replace(/[\r\n\t]/g, ' ') + "__p.push('";
        })
        .replace(/\r/g, '\\r')
        .replace(/\n/g, '\\n')
        .replace(/\t/g, '\\t')
        + "');}return __p.join('');";
    var func = new Function('obj', tmpl);
    return data ? func(data) : func;
};

generates JavaScript with a with-statement in it. The two obvious routes are:

  1. modify Underscore.js's _.template not to generate withs
  2. coerce Closure into playing nice

Is the second option possible?

like image 954
hughdbrown Avatar asked Aug 22 '26 21:08

hughdbrown


1 Answers

Generally, the JS engines perform better without "with", so if generating it without "with" is an option that is likely the best solution.

Otherwise your options depend on whether you are hoping to using Closure Compilers ADVANCED mode. In SIMPLE mode, the compiler won't rename your properties on the template, and will assume that any undeclared variable are globals. So as long are your template object isn't causing any local variables to be shadowed it might "just work".

like image 152
John Avatar answered Aug 25 '26 17:08

John



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!