用nodejs预编译Emberjs Handlebar模板的简单方法是什么?

我很享受emberjs,想要在我的一些小的移动应用程序中进行下一步操作,并预编译我的Ember / Handlebars模板,作为构build过程的一部分。

我宁愿远离搞乱Ruby,也想使用node.js,因为我更喜欢使用它。

我相信我想要使用的是Ember.Handlebars.precompile,但不幸的是我无法在节点环境中加载规范的ember.js文件。 来自节点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 --- 

我想我已经想出了如何在我的代码中设置它们,以便它们能够正确地使用我的视图,我只是想在浏览器DOM之外的环境中编译它们。

代替获得规范的ember.js加载节点,是否有一套特定的文件,我可以采取从余烬回购,并用于编译我的模板?

编辑我做了一个kluge修复工程很好,但得到维修性的F。 我抓住了所有的Handlebars代码减去对window对象的引用。 然后我跟着Ember.Handlebars.Compiler代码,用Object.createreplaceEmber.create ,导出我的Ember对象,并且在节点中看起来非常棒的东西(因为它的工作方式和生成的函数都是模板)。 但是由于前面提到的维护问题,我不认为这是我自己问题的答案,所以仍然可以回答。

编辑2上面原来是一个总失败。 也许在程序中有问题,但使用Ember.Handlebars.precompileEmber.Handlebars.compile不起作用。 模板被创build,但是当我在我的代码中使用附加到Ember.TEMPLATES的预编译模板时,它们不起作用。 我似乎只能在模板显式传递到修改的脚本标记中时才能使模板工作,正如在emberjs.com网站上所build议的那样。

编辑3我想清楚我做错了什么。 我的答案在下面。

我写了一个名为grunt-ember-handlebars的咕噜插件,完全是这样的。 它几乎模仿加思的剧本,有一个重要的区别:

它使用lib / headless-ember.js和lib / ember.js,通过ember.js维护(至less现在)来预编译默认模板 。 如果你不想使用grunt,你可以从tasks / ember-handlebars.js的precompile_handlebars助手中提取相关的代码。

我已经发布了一个带有与handlebars命令行工具类似接口的ember-precompiler版本 。 您可以从NPM安装它:

 npm install -g ember-precompile 

然后运行它为:

 ember-precompile template... [-f OUTPUT_FILE] 

它基本上做了你所描述的(以及主要版本):模拟运行Ember和Handlebars所需的缺失组件,编译模板并将它们添加到Ember.TEMPLATES

find一个足够好的解决scheme,我的问题似乎很容易维护,我会考虑我的问题解决。

以下是我解决问题的方法:

  • 抓取我需要预编译的余烬模板的最小量的代码。
    • 将这些花括号的内容复制到一个文件中。 这个文件位于emberjs回购: https : //github.com/emberjs/ember.js/blob/master/packages/handlebars/lib/main.js
    • 在代码中,findwindow.Handlebars = Handlebars;的一个实例window.Handlebars = Handlebars; 并删除它。
    • 附加Ember模板编译器和车把覆盖的内容。 该文件位于emberjs回购: https : //github.com/emberjs/ember.js/blob/master/packages/ember-handlebars/lib/ext.js
    • findEmber.create所有实例并改为Object.create
  • 简单的预编译程序的大纲:
    • 使用var Ember = require('./my_ember_precompiler').Ember加载代码。
    • 以stringforms获取模板,并使用var templateString = Ember.Handlebars.precompile(str).toString()编译它们。
    • 这将是不同的应用程序,但Ember似乎需要预编译模板的注册。 加载后,为每个创build的模板,我们需要注册我们的模板。 基本上在调用Handlebars.template()包装templateString,并确保将此包装函数添加到Ember.TEMPLATES对象中。

上面的代码在脚本中是自动化的。

看看npm软件包Ember-Runner

以下gist包含一个nodejs构build脚本,它将预编译给定文件夹中的所有.handlebars文件:

https://gist.github.com/1622236

我写了一个正式的预编译程序npm模块给任何其他人可能想要做这个w /最近版本的ember.js

https://npmjs.org/package/ember-template-compiler

安装和使用很简单(下面的例子)

npm安装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 + ");"; 

https://github.com/emberjs/ember-rails查看官方ember-rails gem的代码

虽然它不是一个node.js项目,但它确实展示了如何使用Rails 3.1+资产pipe道预编译模板,并且它包含了所有必要的Javascript代码,您需要在Node中执行这些代码,而无需将解决scheme你必须自己维护。

更具体地说,看看vendor / assets / javascripts / ember-precompiler.js和lib / ember-rails / hjs_template.rb

我远离Node上的专家(显然,Rails更多的是我的东西),但我认为这两个文件应该指向正确的方向。 基本上,你会想要用ember.js连接ember-precompiler.js(它充当缺less更好的单词的“shim”),然后调用EmberRails.precompile来编译你的模板。

窗口对象可以被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'); 

现在你可以运行任何东西从Ember包括Ember.Handlebars.compile