Background
- 我在JavaScript中使用Handlebars模板,这是SpringMVC 3.x Web应用程序的一部分。
- 项目构建是使用 ant 完成的。
- Node.js 和 Ruby 在 Linux 服务器上都不可用。
问题
- 我想将 Handlebars 模板预编译为 JavaScript 作为构建过程的一部分。
- 也就是说,我不想在本地预编译模板,然后必须将生成的代码签入源代码管理。
- 如果没有 Node.js 或 Ruby,服务器不支持 Handlebars npm 包或 Ruby gem,所以我不能走直截了当的路线。
B. 试图解决问题
Gems-in-a-jar 在 Compass 中效果很好,但 Handlebars gem 依赖于原生扩展,JRuby 与原生扩展配合不佳,也不会构建它们。我尝试了几个建议的解决方案,但没有运气。
其他注意事项
我看了一下车把.java但这似乎更适合在应用程序范围内使用车把模板,这对我来说感觉有点矫枉过正。
我正在寻找一种轻量级解决方案,它不会产生很多依赖项,并希望尽可能避免潜在的维护难题。
我根据一篇关于使用 Rhino 预编译 Handlebars 的博客文章整理了一个解决方案。它包括:
- 一些预编译 Handlebars 模板的 JavaScript。
- 使用 Rhino 执行 JavaScript 的 ant 任务。
原始 JavaScript 希望所有模板都位于同一目录中,并将所有生成的 JavaScript 连接成一个文件。我有多个目录的模板,并希望将它们中的每一个预编译为一个单独的文件,所以我的 JavaScript 有点不同,就像 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>
我自己刚刚遇到了这个问题(减去 ANT 集成(,并使用 Phantom JS(作为一个小型的独立可执行文件可以轻松地与您的代码签入并从您选择的任何构建脚本执行(和一个小型 JavaScript 运行器 - 请参阅此要点。
这将采用一个源 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的需求,我只是懒惰!