Reputation: 1092
I'm enjoying emberjs a lot and would like to take the next step in a couple of my small, mobile apps and precompile my Ember/Handlebars templates as part of my build process.
I'd prefer to stay away from messing with Ruby and would like to use node.js as I'm more comfortable with using it.
I believe what I want to use is Ember.Handlebars.precompile, but unfortunately I'm unable to load the canonical ember.js file in a node environment. Example of a naive attempt from the node repl:
> var e = require('./ember');
ReferenceError: window is not defined
at /Users/jeremyosborne/git/projects/ldls/client/lib/emberjs/src/ember.js:5:1
at Object.<anonymous> (/Users/jeremyosborne/git/projects/ldls/client/lib/emberjs/src/ember.js:1596:2)
--- stack trace, you get the idea ---
I think I've already figured out how to set them up in my code so that they work correctly with my views, I just want to compile them in an environment outside of a browser DOM.
In lieu of getting the canonical ember.js to load in node, are there a specific set of files that I can pluck from the ember repo and use to compile my templates?
EDIT
I did a kluge fix that works great but gets an F for maintainability. I grabbed all the Handlebars
code minus the reference to the window
object. Then I followed with the Ember.Handlebars.Compiler
code, replacing Ember.create
with Object.create
, exporting my Ember
object, and viola things work seemingly great in node (as in it works and the functions produced are templates). But I don't consider this an answer to my own question due to the aforementioned maintainafail, so still open for answers.
EDIT 2
The above turns out to be a total fail. Perhaps there's something wrong in the procedure, but using Ember.Handlebars.precompile
or Ember.Handlebars.compile
doesn't work. The templates get made, but when I use the precompiled templates attached to Ember.TEMPLATES in my code, they do not work. I only seem to be able to get templates to work when they are explicitly passed in the modified script tags, as suggested on the emberjs.com site.
EDIT 3 I figured out what I was doing wrong. My answer is below.
Upvotes: 11
Views: 6825
Reputation: 27399
I wrote an official precompiler npm module for anyone else who might be wanting to do this w/ a recent version of ember.js
https://npmjs.org/package/ember-template-compiler
It's simple to install and use (example below)
npm install ember-template-compiler
var compiler = require('ember-template-compiler');
var template = fs.readFileSync('foo.handlebars').toString();
var input = compiler.precompile(template).toString();
var output = "Ember.TEMPLATES['foo'] = Ember.Handlebars.template(" + input + ");";
Upvotes: 1
Reputation: 5173
window object can be mocked by jsdom
var jsdom = require("jsdom").jsdom;
global.document = jsdom("<html><head></head><body></body></html>");
global.window = document.createWindow();
global.$ = global.jQuery = window.$ = window.jQuery = require("jquery");
global.Handlebars = window.Handlebars = require('handlebars');
global.Application = window.Application = {};
require('ember.js');
and now you can run anything from Ember including Ember.Handlebars.compile
Upvotes: 0
Reputation: 5591
I've published a version of ember-precompiler with a similar interface to the handlebars
command line utility. You can install it from NPM:
npm install -g ember-precompile
and then run it as:
ember-precompile template... [-f OUTPUT_FILE]
It does essentially what you describe (and what the gist versions do too): mock out the missing components needed to run Ember and Handlebars, compile the templates and add them to Ember.TEMPLATES
.
Upvotes: 5
Reputation: 93
I've written a grunt plugin called grunt-ember-handlebars that does exactly this. It pretty much mimics Garth's script, with one important difference:
It uses lib/headless-ember.js and lib/ember.js, which are maintained (at least for now) by ember.js to precompile default templates. If you don't want to use grunt, you can extract the relevant code from the precompile_handlebars helper in tasks/ember-handlebars.js.
Upvotes: 7
Reputation: 545
Look at the code for the official ember-rails gem at https://github.com/emberjs/ember-rails
While it's not a node.js project, it does show you how to precompile the templates using the Rails 3.1+ asset pipeline, and it includes all the necessary Javascript code that you would need to do it in Node without having to hack together a solution that you'd have to maintain on your own.
More specifically, look at vendor/assets/javascripts/ember-precompiler.js and lib/ember-rails/hjs_template.rb
I'm far from an expert on Node (obviously, Rails is more my thing).. but I think those two files should point you in the right direction. Basically, you're going to want to concatenate ember-precompiler.js (which acts as a "shim" for lack of a better word) with ember.js and then call EmberRails.precompile to compile your templates.
Upvotes: 0
Reputation: 555
The following gist contains a nodejs build script that will precompile all .handlebars files in a given folder:
https://gist.github.com/1622236
Upvotes: 1
Reputation: 1092
Found a good enough solution to my problem that seems easy enough to maintain that I'll consider my problem solved.
Here's how I solved things:
window.Handlebars = Handlebars;
and remove it.Ember.create
and change to Object.create
.var Ember = require('./my_ember_precompiler').Ember
.var templateString = Ember.Handlebars.precompile(str).toString()
.Handlebars.template()
and make sure this wrapped function is added to the Ember.TEMPLATES
object.The above is painless when it's automated in a script.
Upvotes: 5