Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions doc/why-tmodjs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## 前端模板

早期,开发人员都是直接在 js 文件中采用最原始的方式直接拼接 HTML 字符串:
早期,开发人员都是直接在 JS 文件中采用最原始的方式直接拼接 HTML 字符串:

var html = '';
for (var i = 0, users = data.users; i < users.length; i ++) {
Expand All @@ -18,7 +18,7 @@

这种方式刚开始在一两个简单的页面中还是比较灵活的,但弊端也十分明显:UI 与逻辑代码混杂在一起,阅读起来会非常吃力。一旦随着业务复杂起来,或者多人维护的情况下,几乎会失控。

jquery 作者的 tmpl 模板引擎影响,从 09 年开始到现在,前端模板引擎出现了百花齐放的局面,涌现出一大批行色各异的引擎,几乎每个前端工程中都使用了模板引擎。一条前端模板类似这样:
jQuery 作者的 tmpl 模板引擎影响,从 09 年开始到现在,前端模板引擎出现了百花齐放的局面,涌现出一大批形色各异的引擎,几乎每个前端工程中都使用了模板引擎。一条前端模板类似这样:

<script id="user_tmpl" type="text/html">
{{each users as value}}
Expand All @@ -28,7 +28,7 @@
{{/each}}
</script>

它使用一个特殊的``<script type="text/html"></script>``标签来存放模板(由于浏览器不支持这种类型的声明,它存放的代码不会当作 js 运行,代码也不会被显示出来)。使用模板引擎渲染模板的示例:
它使用一个特殊的``<script type="text/html"></script>``标签来存放模板(由于浏览器不支持这种类型的声明,它存放的代码不会当作 JS 运行,代码也不会被显示出来)。使用模板引擎渲染模板的示例:

var html = tmpl('user_tmpl', data);
document.getElementById('content').innerHTML = html;
Expand All @@ -41,27 +41,27 @@

### 开发调试

每次修改前端模板需要改动页面的代码,如果不是纯静态页面,无法使用类似 fiddler 的工具将页面映射到本地进行开发,开发调试依赖只能服务端环境,效率低下。
每次修改前端模板需要改动页面的代码,如果不是纯静态页面,无法使用类似 Fiddler 的工具将页面映射到本地进行开发,开发调试只能依赖服务端环境,效率低下。

### 自动化构建

在现代 web 前端工程体系中,几乎每一个环节都拥有相应的优化工具,这些几乎都被 grunt 这个自动构建工具连接起来。但是前端模板若内嵌到页面中,复杂度会比较高,现有工具因为受限难以进行自动优化。
在现代 web 前端工程体系中,几乎每一个环节都拥有相应的优化工具,这些几乎都被 Grunt 这个自动构建工具连接起来。但是前端模板若内嵌到页面中,复杂度会比较高,现有工具因为受限难以进行自动优化。

### 模块化

前端模板集中在一个文件中这必然会引起多人协作的问题,随着项目复杂度增加,按文件模块化迫在眉睫。

## 现有的模板外置解决方案

目前越来越的项目已经将模板从页面中迁移出来,主要有两种方式:
目前越来越多的项目已经将模板从页面中迁移出来,主要有两种方式:

### ajax 拉取方案
### AJAX 拉取方案

通过 ajax 加载远程模板,然后再使用模板引擎解析。这种方式的好处就是模板可以按文件存放,书写起来也是十分便利,但弊端相当明显:由于浏览器同源策略限制的,导致模板无法部署到 CDN 网络中。
通过 AJAX 加载远程模板,然后再使用模板引擎解析。这种方式的好处就是模板可以按文件存放,书写起来也是十分便利,但弊端相当明显:由于浏览器同源策略限制,导致模板无法部署到 CDN 网络中。

### 在 JS 文件中存放模板

为避免上述加载模板方案无法跨域的致命缺陷,模板存放在 js 文件中又成了最佳实践方式,但是这种情况下需要对回车符进行转义,对书写不友好,严重影响开发效率。例如:
为避免上述加载模板方案无法跨域的致命缺陷,模板存放在 JS 文件中成了最佳实践方式,但是这种情况下需要对回车符进行转义,对书写不友好,严重影响开发效率。例如:

var user_tmpl =
'{{each users as value}}\
Expand All @@ -84,8 +84,8 @@
组织方式 | 开发效率 | 优化空间 | 本地调试 | 代码复用 | 团队协作
------ | ------ | ------ | ------ | ------ | ------
内嵌业务页中 | ✓ | ✗ | ✗ | ✗ | ✗
Ajax 远程加载 | ✓ | ✗| ✓ | ✓ | ✓
嵌入 js 文件 | ✗ | ✓ | ✓ | ✓ | ✓
AJAX 远程加载 | ✓ | ✗| ✓ | ✓ | ✓
嵌入 JS 文件 | ✗ | ✓ | ✓ | ✓ | ✓

总结:方便优化的模式不利于开发;利于开发的模式不利于优化。

Expand All @@ -111,21 +111,21 @@ template('tpl/home/main', data)

* 浏览器对文本加载会有跨域限制
* 浏览器同步加载会引起界面卡顿
* 加载大量的模板文件会带来 http 资源消耗问题
* 加载大量的模板文件会带来 HTTP 资源消耗问题

## 解决方案

为了实现上述“理想模式”,我们推出了 TmodJS——模板预编译器,以下是它的简介:
为了实现上述“理想模式”,我们推出了 TmodJS —— 模板预编译器,以下是它的简介:

> TmodJS(原名 atc)是一个简单易用的前端模板预编译工具。它通过预编译技术让前端模板突破浏览器限制,实现后端模板一样的同步“文件”加载能力。它采用目录来组织维护前端模板,从而让前端模板实现工程化管理,最终保证前端模板在复杂单页 web 应用下的可维护性。同时预编译输出的代码经过多层优化,能够在最大程度节省客户端资源消耗。
> TmodJS(原名 atc)是一个简单易用的前端模板预编译工具。它通过预编译技术让前端模板突破浏览器限制,实现后端模板一样的同步“文件”加载能力。它采用目录来组织维护前端模板,从而让前端模板实现工程化管理,最终保证前端模板在复杂单页 Web 应用下的可维护性。同时预编译输出的代码经过多层优化,能够在最大程度节省客户端资源消耗。

它采用三种方案来解决难题:

### 1.本地构建

模板编写完成后,通过一个本地工具将模板编译成浏览器可执行的代码——js,这样就可以用脚本的方式来加载模板,不必受浏览器的同源策略限制,模板可以部署到任意 CDN,而无需处理跨域问题。
模板编写完成后,通过一个本地工具将模板编译成浏览器可执行的代码 —— JS,这样就可以用脚本的方式来加载模板,不必受浏览器的同源策略限制,模板可以部署到任意 CDN,而无需处理跨域问题。

工具内部采用模板引擎——[artTemplate](https://github.com/aui/artTemplate) 完成模板编译,输出 js 文件。artTemplate 也是来自腾讯的开源项目,它支持预编译,编译后的代码可以无需引擎运行。
工具内部采用模板引擎 —— [artTemplate](https://github.com/aui/artTemplate) 完成模板编译,输出 js 文件。artTemplate 也是来自腾讯的开源项目,它支持预编译,编译后的代码可以无需引擎运行。

### 2.种子文件

Expand All @@ -137,7 +137,7 @@ template('tpl/home/main', data)

### 3.模板目录

为了让团队成员、自动化工具能更好的管理模板,前端模板不再内嵌到页面中,而是使用专门的目录进行组织维护;使用路径作为模板的 ID,这样与源文件保持对应关系——这样好处就是极大的增加了可维护性。例如:页面头部底部的公用模板可以放在``tpl/public``目录下,首屏的模板可以放在``tpl/home``下面。
为了让团队成员、自动化工具能更好的管理模板,前端模板不再内嵌到页面中,而是使用专门的目录进行组织维护;使用路径作为模板的 ID,这样与源文件保持对应关系 —— 这样好处就是极大的增加了可维护性。例如:页面头部底部的公用模板可以放在``tpl/public``目录下,首屏的模板可以放在``tpl/home``下面。

## 模板与工程化

Expand All @@ -147,7 +147,7 @@ TmodJS 采用了自动编译机制,一经启动后就无需人工干预,每

TmodJS 编译之前会压缩掉模板的空白字符,编译为 js 后又会进行一次压缩,此时输出的 js 甚至会比原始模板更小(最高可减少一半的体积)。

在默认设置下,TmodJS 会将模板目录所有模板编译后再进行压缩与合并,输出后的 template.js 称之为模板包(内部名称叫 TemplateJS 格式)这种打包的方式非常适合移动端单页 WebApp,输出后的模板包可直接可作为开发阶段与线上运行的文件,适合中小型项目。
在默认设置下,TmodJS 会将模板目录所有模板编译后再进行压缩与合并,输出后的 template.js 称之为模板包(内部名称叫 TemplateJS 格式)这种打包的方式非常适合移动端单页 WebApp,输出后的模板包可直接作为开发阶段与线上运行的文件,适合中小型项目。

[查看编译后的模板示例](http://microtrend.cdc.tencent.com/tpl/dist/template.js)

Expand All @@ -157,7 +157,7 @@ TmodJS 编译之前会压缩掉模板的空白字符,编译为 js 后又会进

### 本地调试

因为模板已经被独立出来,所以使用 fiddler 将线上模板映射到本地进行开发调试将十分容易。如果线上模板报错,开启 TmodJS 的``debug``模式后可以直接找到出错的模板路径以及所在行号,例如:
因为模板已经被独立出来,所以使用 Fiddler 将线上模板映射到本地进行开发调试将十分容易。如果线上模板报错,开启 TmodJS 的``debug``模式后可以直接找到出错的模板路径以及所在行号,例如:

Template Error

Expand Down