Skip to content

构建自己的静态网站生成脚本(二)

此篇来讲模版引擎的实现,筛选之后,比较喜欢的模版引擎有如下几个:

edge

@if(happy && hungry)
I am happy _and_ hungry; both are true.
@endif

{{ foo ? "true" : "false" }}

lit-html

js
import { html } from "lit-html";
const helloTemplate = (name) => html`<div>Hello ${name}!</div>`;
  • 谷歌出品的 lit.js 前端框架的工具包
  • 有配套的官方 VSCode 插件来提供代码高亮
  • 代码高亮需要识别 lit-html 的 html 标签函数调用
  • npm 地址:https://www.npmjs.com/package/lit-html

通用 html VSCode 代码支持解决方法

打开:设置 => 文本编辑器 => 文件 => Associations => 添加项

  • edge
    • 添加项:*.edge
    • 添加值:html
  • temp.js
    • 添加项:*.temp.js
    • 添加值:html

这样可以基本解决 html 的高亮、补全、提示、格式化,但是这样同时也失去了 js 的相关支持

js 最简模版引擎实现

关于 js 想要实现尽量原生的模版引擎,必然要使用模版字符串,模版需要被构造成函数随处调用,但是 js 是没有提供模版字符串的构造函数的,初步有两种思路:

  • 直接将模版封装成 js 函数,返回将参数处理之后的模版字符串;
  • 将模版写入文本文件,如 html 文件,脚本运行时读入模版内容,通过 Function 函数动态创建模版函数
js
const render = (t) => new Function("$", `return \`${t}\``);

temp.js

js
// template.js
export const template = (name) => `<p>${name}<p>`;
  • 使用 js 的模版字符串来写函数式模版,使用 ESModule 高灵活度组件化
  • 写在 js 文件中,没有 html 的语法高亮、自动补全提示和代码格式化

Function 动态创建模版函数

html
<!-- tempalte.html -->
<p>${$.title}</p>
  • 在 html 文件中模版字符串的语法,使用编辑器默认提供的相关代码支持,同时失去编辑器对模版中逻辑代码的支持
  • 组件化需要预先读入所有模版,随模版上下文对象一起注入,稍显麻烦

尝试编写 temp.js demo,函数式模版确实灵活,但没有编辑器的相关支持代码非常混乱,难以阅读,于是先转头实现了 Function 动态创建模版函数的模版引擎,以及从上下文注入所有模版函数的组件化。

js
// 把模板文件解析为函数
const x = (x) => new Function("$", `return \`${readFileSync(x, "utf-8")}\``);

// 读入所有模板
function readTemplate(dir = "./template") {
  const tems = {};
  readdirSync(dir).forEach((v) => {
    try {
      // 在模版文件中使用反引号时需要转义,否则会创建模版函数失败
      tems[v.replace(/\.html$/, "")] = x(resolve(dir, v));
    } catch {
      // 对创建失败抛出错误,提示报错文件
      throw new Error(
        `Error reading "${v}" template file, please check the part related to backquotes or escape symbols in the file.`
      );
    }
  });
  return tems;
}
Release time: 6/19/2022, 1:08:00

Last updated:

⟣ Growing, with you. ⟢