聊聊scratch-engine,一个前端模板引擎

一个简介

scratch-engine是一个由我自己开发的非常简单的纯js前端模板引擎。引擎挂载在HTML页面上,通过识别并匹配对应语言包中对应值来替换预设的模板标签。

开始

开发scratch的原因是目前在做的一个Web项目中,需要实现页面多语言支持。因为之前的一些问题,这个Web项目仅仅通过js异步请求API数据的形式来进行页面渲染,没有使用Node等后台框架,无法使用多语言插件。而且在看过i18n这类多语言模块和mustache这类模板引擎后,感觉都不能完全满足需求(或者是因为不会用……)。于是决定用javascript自己写一个多语言渲染的前端引擎。

思路

首先,开发语言选择javascript是毫无疑问的,简单方便,直接浏览器就可以运行。其次为了提高效率,减少依赖,所以使用原生的javascript操作HTML文档来进行渲染。这时候一般有两种思路。一个是操作DOM树进行节点替换,这样更符合页面操作的一般思路,理论上来说,效率也更高;另一种比较朴素的想法是,将整个文档流读入再搜索标签替换,HTML内容较多时效率可能偏低。但是考虑到DOM操作时,必须要用节点替换节点,在一些纯文本场景下(如博客、笔记类页面)会产生多余的标签,故采用了读入文档流的方案。最后,考虑到多语言页面可能需要多次渲染,想到了设定一个把原始文档(带模板标签)存入localStorage以便重复渲染的motion模式。

开发

方案定下来了就非常简单了。首先,我们需要把语言包读入。没有语言包,其他工作都是白搭。因为javascript没有权限操作文件,这个时候需要用到XMLHttpRequest向服务器发出异步请求来获取。获得文件后,再使用document.documentElement.innerHTML拿到整个页面的HTML文件流。后面就是纯粹的搜索替换了。我使用的是indexOf函数,搜索模式是惯用的双指针渐进(自己创造的……),即类似于:

while (true) {
  // Some code
  prev = stream.indexOf(str, next);
  next = stream.indexOf(str, prev);
  // Other code
}

这样的话就能保证每次都能从原来的位置往后找。但是在这种方法寻找时需要注意,由于原来模板标签和替换后的字符串长度不一定相同,这时候后指针需要进行一次回退(有时是前进),否则可能导致两个相邻的模板标签不能读到的状况。我为了减少计算(偷懒),直接使后指针等于前指针(因为一般来说前指针的位置总是正确的)。还有一个要提到的是,替换字符串我使用的是slice,将标签前后的字符流分别切下,再将替换内容拼接上即可。如果不存在对应内容在语言包则用特定字符串填充。最后,补充一些必要的机动性内容(如语言包存放位置可供设置),再配以对应的设置函数,整个引擎就算开发完成了。

展望

因为临近期末考,js编程能力也很有限,所以整个scratch-engine非常非常简单,没有什么技术含量。不过个人认为,相对于后台的渲染引擎,前端渲染引擎有响应速度上的优势,而且基本上是即插即用(在页头引用js文件后代码触发即可),非常适合一些依赖文本的静态网站和轻应用。而且如果在初次渲染时(即用户可能看到模板标签)做一些优化工作,提升加载速度,用户体验能够上升一个档次,前端的渲染引擎也能成为Web开发者的好伙伴。

卖广告

欢迎大家在自己的项目中尝试使用scratch-engine并提出意见建议!scratch-engine的项目地址: https://github.com/JerryLiao26/scratch-engine