如何将Handlebars预编译集成到没有Node.js / Ruby的ant构建中?

时间:2014-08-12 19:34:54

标签: ant handlebars.js jruby

背景

  • 我在JavaScript中使用Handlebars模板,这是SpringMVC 3.x Web应用程序的一部分。
  • 项目构建使用ant。
  • 完成
  • Linux服务器上既没有Node.js也没有Ruby。

问题

  • 我想将Handlebars模板预编译为JavaScript,作为构建过程的一部分。
  • 也就是说,我不想在本地预先编译模板,然后必须将生成的代码检查到源代码管理中。
  • 如果没有Node.js或Ruby,服务器不支持Handlebars npm包,也不支持Ruby gem,所以我不能直接使用。

尝试解决

Gems-in-a-jar适用于Compass,但Handlebars gem依赖于原生扩展,而JRuby不能很好地使用原生扩展,也不会构建它们。我尝试了几个proposed solutions,但没有运气。

其他说明

我查看了Handlebars.java,但这似乎更倾向于在应用程序范围内使用Handlebars模板,这对于我的目的来说有点过分。

我正在寻找一种轻量级的解决方案,它不会产生很多依赖性,并希望尽可能避免潜在的维护问题。

2 个答案:

答案 0 :(得分:2)

我根据blog post about precompiling Handlebars with Rhino整理了一个解决方案。它包括:

  • 预编译Handlebars模板的bit of JavaScript
  • 使用Rhino执行JavaScript的ant任务。

原始JavaScript希望所有模板都在同一目录中,并将所有生成的JavaScript连接到一个文件中。我有多个目录的模板,并希望将每个目录预先编译为单个文件,因此我的JavaScript is a little different和ant任务一样:

<target name="handlebars">
  <apply executable="java" dest="${javascript.dir}">
    <arg value="-jar"/>
    <arg path="${lib-ext.dir}/rhino.jar"/>
    <arg value="${lib-ext.dir}/rhino-handlebars-precompiler.js"/>
    <arg value="--handlebars"/>
    <arg value="${javascript.dir}/handlebars/handlebars.js"/>
    <arg value="--template"/>
    <srcfile/>
    <arg value="--output"/>
    <targetfile/>
    <fileset id="fileset" dir="${javascript.dir}">
      <include name="**/*.tmpl" />
    </fileset>
    <mapper type="glob" from="*.tmpl" to="*.tmpl.js"/>
  </apply>
</target>

答案 1 :(得分:1)

我自己刚刚遇到这个问题(减去ANT集成),并使用Phantom JS解决了这个问题(作为一个小的独立可执行文件,可以很容易地使用您的代码签入并从任何构建脚本中执行选择)和一个​​小的javascript跑步者 - 见this gist

这将包含一个包含一个或多个把手模板的源HTML文件或包含在具有任意类名的标签中的部分,以标识要拾取的脚本,例如:

<script type="text/x-handlebars-template" class="hbTemplate" id="MyFabulousTemplate">
    <p>This template is FABULOUS - hello {{username}}!!!</p>
</script>

从命令行开始执行以下操作:

phantomjs hbcompiler.js filewithtemplatesin.html hbTemplate hbPartial MyTemplates

哪个会预编译源HTML中的所有模板,并将它们输出到stdout,如:

if (MyTemplates === undefined) var MyTemplates = {};
if (MyTemplates.pcTemplates === undefined) MyTemplates.pcTemplates = {};
if (MyTemplates.pcPartials === undefined) MyTemplates.pcPartials = {};

MyTemplates.pcTemplates["MyFabulousTemplate"] = (pre-compiled-template-definition)
MyTemplates.pcTemplates["MySecondTemplate"] = (pre-compiled-template-definition)
...

然后您可以在JS中使用以下内容:

var template = Handlebars.template(MyTemplates.pcTemplates["MyFabulousTemplate"]);
// Then for e.g. execute the template and put the resulting output in the element with
// ID "target":
$("#target").html(template({ username: "CheeseMonger" }));

这一切都有点被黑了,但它适用于我的用例。就目前而言,它需要jquery和(当然)已知位置的把手库(请参阅要点上的路径的第50-51行),但这可以很容易地考虑到更多参数或其他任何因素。您可以轻松地重新编写它以消除对jquery的需求,我只是懒惰!