通过Nodemon实现Handlebars模板更新后自动执行预编译

115 阅读3分钟

一、背景和意义

Handlebars常用的HTML模板引擎之一,在使用Handlebars的过程中,经常会使用到Handlebars预编译器,因为预编译Handlebars模板可以节省客户端时间并减少Handlebars库所需的运行时大小。Handlebars的官方示例 https://www.handlebarsjs.cn/installation/precompilation.html 给出了预编译的命令示例:

handlebars example.handlebars -f example.precompiled.js

但是该命令是手动执行的,但在实际开发中,修改完代码再手动执行有些麻烦,最好是改完文件后就能自动执行。 Nodemon是nodejs常用工具,主要用于监视node.js应用程序中的代码文件更改并自动重启服务。结合使用Nodemon可以实现handlebars模板文件修改之后自动执行预编译的命令,文本将给出相关示例。

二、给Handlebars官方示例增加自动预编译功能

这里沿用Handlebars官方示例,先创建一个文件 example.handlebars 来包含模板:

Handlebars <b>{{doesWhat}}</b> 预编译!

然后运行预编译器:

handlebars example.handlebars -f example.precompiled.js

然后在HTML页面中引用 Handlebars 运行时和预编译的 JavaScript:

<div id="output"></div>
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.runtime.js"></script>
<script src="example.precompiled.js"></script>
<script>
  var template = Handlebars.templates.example;
  document.getElementById('output').innerHTML = template({doesWhat: 'rocks!'})
</script>

不过如果直接运行Handlebars的官方示例,得到的页面显示结果可能是这样:

image.png

还需要在HTML前面增加字符集设置:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

这样才能展示预期的结果:

image.png

接下来使用nodemon,执行命令:

nodemon --watch example.handlebars --exec 'handlebars example.handlebars -f' example.precompiled.js

其中 --watch example.handlebars 表示监控example.handlebars这个文件的变化,--exec 'handlebars example.handlebars -f' 表示在最开始运行之时以及文件变化之后执行命令handlebars example.handlebars -f 再加上最后的文件名 example.precompiled.js,即执行 handlebars example.handlebars -f example.precompiled.js,运行结果如下图所示:

image.png

[nodemon] starting ... 这一段输出日志中看到执行的命令与预期相符。接下来将example.handlebars 中的内容修改为:

Handlebars <b>{{doesWhat}}</b> 预编译-version 0!

可以看到控制台中多了两行日志:

image.png

访问对应的HTML页面,输出内容也出现了相应的变化:

image.png

三、处理多个模块文件的情况

有时候可能会将多个模板文件预编译成一个js文件,例如预编译命令为:

handlebars example.handlebars example2.handlebars example3.handlebars -f example.precompiled.js

这种情况下,nodemon命令需要修改为:

nodemon -w example.handlebars -w example2.handlebars -w example3.handlebars --exec 'handlebars example.handlebars example2.handlebars example3.handlebars -f' example.precompiled.js

由于这里要监视的文件列表较多,所以将--watch简写成-w

在实际应用中,也经常是将多个预编译到同一个js文件的模板都放在同一目录,比如将 example.handlebars example2.handlebars example3.handlebars 三个文件都放在template目录,那么nodemon命令调整为:

nodemon -w template/ -e handlebars --exec 'handlebars template/example.handlebars template/example2.handlebars template/example3.handlebars -f' example.precompiled.js

其中-w template/表示监视template目录,-e handlebars表示监视扩展名为handlebars的文件。

四、将nodemon命令加入到package.json中

前面的nodemon命令比较长,在实际中不太可能手动输入这些命令,否则反而影响开发效率。但可以将这个冗长的nodemon命令写入package.json配置文件中,例如:

{
  "name": "handlebars-example",
  "version": "1.0.0",
  "scripts" : {
    "example_precp": "nodemon -w template/ -e handlebars --exec 'handlebars template/example.handlebars template/example2.handlebars template/example3.handlebars -f' example.precompiled.js"
  }
}

在这个package.json配置文件中,scripts中的第一项example_precp就是之前的nodemon命令。执行npm run example_precp,却发现报错了:

image.png

试着把--exec参数的单引号改成双引号,将package.json改成:

{
  "name": "handlebars-example",
  "version": "1.0.0",
  "scripts" : {
    "example_precp": "nodemon -w template/ -e handlebars --exec \"handlebars template/example.handlebars template/example2.handlebars template/example3.handlebars -f\" example.precompiled.js"
  }
}

修改之后可以执行成功:

image.png