Handlebars.js: NPM Handlebars can't read it's own precompiled data

Created on 30 May 2015  ·  4Comments  ·  Source: handlebars-lang/handlebars.js

Per the Handlebars documentation, the templateSpec generated by Handlebars.precompile() should be directly consumable by Handlebars.template(), however it's clear from the error stack I get that the former outputs a string and the latter expects an object.

Here is a contrived example that recreates the problem.

var Handlebars = require('handlebars');

console.log(Handlebars.VERSION);

var pre = Handlebars.precompile('{{foo}}');
var template = Handlebars.template(pre);

And the associated output

$ node contrived.js 
3.0.1

/private/tmp/hbs-bug/node_modules/handlebars/dist/cjs/handlebars/runtime.js:48
    throw new _Exception2['default']('Unknown template object: ' + typeof temp
          ^
Error: Unknown template object: string
    at Object.template (/private/tmp/hbs-bug/node_modules/handlebars/dist/cjs/handlebars/runtime.js:48:11)
    at HandlebarsEnvironment.hb.template (/private/tmp/hbs-bug/node_modules/handlebars/dist/cjs/handlebars.runtime.js:46:20)
    at Object.<anonymous> (/private/tmp/hbs-bug/contrived.js:7:27)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

Most helpful comment

That's what I was afraid of. Instead of using eval though I opted to use a function constructor that I then immediately invoked to give me the actual object. Here's what that looks like should anyone else find it useful.

var preStr = Handlebars.precompile('{{foo}}');
var pre = (new Function('return ' + preStr)());
var template = Handlebars.template(pre);

Seems like something that could be easily integrated into Handlebars.

All 4 comments

Precompile returns a string with the JavaScript source. It's not intended to be run in the same environment as you'd just use the compile method. If you do need to do this for some reason, you should eval this sting before passing to template.

That's what I was afraid of. Instead of using eval though I opted to use a function constructor that I then immediately invoked to give me the actual object. Here's what that looks like should anyone else find it useful.

var preStr = Handlebars.precompile('{{foo}}');
var pre = (new Function('return ' + preStr)());
var template = Handlebars.template(pre);

Seems like something that could be easily integrated into Handlebars.

You're effectively implementing Handlebars.compile without the lazy
compilation. Why are you using precompile for templates you plan to use in
the same instance?
On Sun, May 31, 2015 at 4:42 PM Nathan Witt [email protected]
wrote:

That's what I was afraid of. Instead of using eval though I opted to use a
function constructor that I then immediately invoked to give me the actual
object. Here's what that looks like should anyone else find it useful.

var preStr = Handlebars.precompile('{{foo}}');
var pre = (new Function('return ' + preStr)());
var template = Handlebars.template(pre);

Seems like something that could be easily integrated into Handlebars.


Reply to this email directly or view it on GitHub
https://github.com/wycats/handlebars.js/issues/1033#issuecomment-107249447
.

The script is a development tool for email templates. The precompiled source gets uploaded for use in production but I also generate a complete local preview. I chose not to use compile because this way I can get both from a common source.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

morgondag picture morgondag  ·  5Comments

jlubean picture jlubean  ·  8Comments

DylanPiercey picture DylanPiercey  ·  7Comments

janus-reith picture janus-reith  ·  3Comments

NickCis picture NickCis  ·  4Comments