我构建了一个比 EJS 快 3 倍的 JS 模板引擎
经过数百小时的开发,我终于在上周发布了我的开源项目。Eta是一个可插拔、轻量级且超快速的 JavaScript 模板引擎,由我创建,旨在作为 doT 和 EJS 的替代方案。
不过,在我开始讨论我的开发历程之前,让我先概述一下 Eta 和 EJS 之间的一些区别。
Eta 与 EJS 的对比:
Eta 的语法与 EJS 非常相似(大多数模板应该可以在任一引擎上运行),Eta 拥有类似的 API,并且 Eta 和 EJS 共享相同的文件处理逻辑。以下是 Eta 和 EJS 之间的区别:
- Eta 更轻量。Eta压缩后大小约为 2KB,而 EJS压缩后大小为 4.4KB
- Eta 编译和渲染模板的速度比 EJS 快得多。查看以下基准测试:https://ghcdn.rawgit.org/eta-dev/eta/master/browser-tests/benchmark.html
- Eta 允许控制左侧空格(使用
-
),这在 EJS 中不起作用,因为 EJS-
在左侧使用 来指示该值不应转义。相反,Eta 使用~
来输出原始值 - Eta 为您提供了更多分隔符的灵活性 -例如,您可以将它们设置为
{{
和,而使用 EJS 则无法做到这一点}}
- Eta 添加插件支持
- Eta 中的注释
/* ... */
允许围绕模板标签进行注释,并且更加一致 - Eta 可以正确解析字符串。例如:
<%= "%>" %>
在 Eta 中可以正常工作,但在 EJS 中无法正常工作 - Eta 公开 Typescript 类型并分发 UMD 构建
- 自定义标签类型前缀。例如:您可以更改
<%=
为<%*
Eta 和 EJS 共享的功能
- 异步支持
- 部分支持
- 文件处理支持
- Eta 的文件处理代码借鉴了 EJS,后者每周下载量超过 150 万次。相当可靠 😉
- Express.js 支持
- EJS 语法高亮工具在一定程度上与 Eta 配合使用
我为什么要创建 Eta?
我的旅程始于大约两年前,当时我第一次创建了一个名为Squirrelly的模板引擎。经过数百小时的性能基准测试和数十种不同的解析方法的尝试,我终于能够超越所有其他流行模板引擎的速度。
在过去的一年里,我一直在开发 Squirrelly 的下一个版本,该版本增加了一些重要的功能,例如模板继承和更好的字符串解析。在对 Squirrelly 进行基准测试时,我发现它比其他模板引擎(例如 EJS)的速度要快得多——尽管它支持助手、过滤器、模板继承等功能。
我决定采用 Squirrelly 背后的框架(包括所有幕后代码),我已经对其进行了充分的优化和测试,并在其之上创建一个简单的嵌入式模板引擎。新的模板引擎将比大多数其他模板引擎更易于配置,极其轻量级,速度极快,并且比大多数其他模板引擎更可靠。
我将新的模板引擎命名为“eta”,原因如下:
1)Eta 在世界语中是“微小”的意思,因此 Eta 是一个微型模板引擎;
2)Eta 是希腊字母表中一个字母的名称,我用它作为一个很酷的标志;
3)“Eta”有 3 个字母长,这使得编写模板文件变得很容易(例如footer.eta
)。
几周之内,我就创建了 Eta。由于无需担心 Squirrelly 的高级功能,Eta 的创建和测试时间显著缩短。使用 Docusaurus v2,我搭建了一个文档网站,并编写了一个 Playground。
一些经验教训
- 在 JavaScript(至少是 v8 引擎)中,正则表达式经过了超级优化,并且比循环遍历字符串中的每个字符并对其进行某些操作要快得多
- TypeScript 捕获了很多愚蠢的错误
- 运行代码覆盖率测试有助于找到不必要的(死)代码
- 通过大量的反复试验可以显著提高性能
with () {}
在 JavaScript 中会减慢执行速度并可能导致令人困惑的错误
Eta 的堆栈
- 用 TypeScript 编写
- 使用 Rollup 进行编译(对于库来说,它创建的构建比 Webpack小得多)
- 使用 rollup-plugin-terser 进行压缩
- 使用 Jest 进行测试
- 使用 Coveralls 进行代码覆盖
- Travis CI 用于持续集成
- 格式化更漂亮
- ESLint 与 StandardJS 兼容,用于 linting
- TypeDoc 用于自动 API 文档生成
希望你喜欢我创建 Eta 的历程!如果你未来的项目需要嵌入式 JavaScript 模板引擎,可以考虑使用 Eta,而不是像 EJS 或 doT 这样的库。
鏂囩珷鏉ユ簮锛�https://dev.to/nebrelbug/i-built-a-js-template-engine-3x-faster-than-ejs-lj8