ali-tmodjs
Version:
Template Compiler
367 lines (258 loc) • 11.6 kB
Markdown
# Ali-TmodJS
为TmodJS增加FMD模块格式,及.art文件的编译支持
安装
```
npm install -g ali-tmodjs
```
模板文件 public/footer.art
```
<div id='footer'>
{{if time}}
<p class='time'>{{time}}</p>
{{/if}}
{{include '../copyright'}}
</div>
```
- 编译类型:``pure-fmd``,只是简单模块化模板文件
```
define("public/footer", function() {
return "<div id=\"footer\">\n{{if time}}\n <p class='time'>{{time}}</p>\n{{/if}}\n{{include '../copyright'}}\n</div>";
});
```
- 编译类型:``fmd``,打包include,helper,template
```
define("public/footer", [ "template", "copyright" ], function(template) {
return template("public/footer", function($data, $filename) {
"use strict";
var $utils = this, time = ($utils.$helpers, $data.time), $escape = $utils.$escape, include = function(filename, data) {
data = data || $data;
var text = $utils.$include(filename, data, $filename);
return $out += text;
}, $out = "";
return $out += '<div id="footer">\n', time && ($out += "\n <p class='time'>", $out += $escape(time),
$out += "</p>\n"), $out += "\n", include("../copyright"), $out += "\n</div>", new String($out);
});
});
```
- 模块id resolve, 针对fmd模块id的resolve匹配替换,默认``null``, 只有type为``pure-fmd``或``fmd``时生效
```
//不用resolve
define("public/footer",function(){})
```
```
//使用resolve:[ "^(.*)","work/$1"]
define("work/public/footer",function(){})
```
Demo请查看 /test/fmdjs.html
> 需自行修改lofty.config配置
- 编译类型:``customize``,完全自定义编译
以下是自定义代码的例子
```
//build.js
var path = require('path');
module.exports = {
"art2js":{
"type":"customize",
"customizePath": path.resolve(__dirname,"./customize.js")
}
}
//customize.js
/**
* 自定义模板编译
* 将模板中的<!--#内容-->,输出成fmd的依赖
* @param {[type]} id 输出的模块id
* @param {[type]} source 模板源码
* @param {[type]} options 编译配置项
* @return {[type]} [description]
*/
module.exports = function(id,source,options){
var dep = source.match(/<!--#\((.*)\)-->/);
if(dep[1]){
dep = dep[1];
}
return "define('"+id+"',['"+dep+"'],"
+ "function(){"
+ "return "+stringify(source)+";"
+ "});";
}
```
---
TmodJS(原名 atc)是一个简单易用的前端模板预编译工具。它通过预编译技术让前端模板突破浏览器限制,实现后端模板一样的同步“文件”加载能力。它采用目录来组织维护前端模板,从而让前端模板实现工程化管理,最终保证前端模板在复杂单页 web 应用下的可维护性。同时预编译输出的代码经过多层优化,能够在最大程度节省客户端资源消耗。
一、**按文件与目录组织模板**
```
template('tpl/home/main', data)
```
二、**模板支持引入子模板**
```
{{include '../public/header'}}
```
TmodJS 一经启动,就无需人工干预,每次模板创建与更新都会自动编译,引入一个 js 即可使用``template(path)``接口调用本地模板文件,直到正式上线都无需对代码进行任何修改,整个过程简单自然。
## 所有特性
0. 编译模板为不依赖引擎的 js 文件
1. 前端模板按文件与目录组织
3. 模板之间支持引入外部模板
4. 使用同步模板加载接口
5. 可选多种规范的模块输出:AMD、CMD、CommonJS, FMD
6. 支持作为 GruntJS 的插件构建项目
7. 模板目录可被前后端共享
8. 支持检测修改即时编译
9. 支持模板运行时调试
10. 配置文件支持多人共享
若想深入了解,请阅读:《[进击!前端模板工程化](https://github.com/aui/tmodjs/blob/master/doc/why-tmodjs.md)》
## 文档目录
* [安装](#安装)
* [编写模板](#编写模板)
* [编译模板](#编译模板)
* [使用模板](#使用模板)
* [演示](#演示)
* [配置](#配置)
* [grunt](#grunt)
* [gulp](#gulp)
* [常见问题](#常见问题)
* [更新日志](#更新日志)
* [加入我们](#加入我们)
* [授权协议](#授权协议)
## 安装
使用 [NodeJS](http://nodejs.org) 附带的``npm``命令,执行:
```
npm install -g ali-tmodjs
```
> Mac OSX 可能需要管理员权限运行: ``sudo npm install -g ali-tmodjs``
## 编写模板
TmodJS 的前端模板不再耦合在业务页面中,而是和后端模板一样有专门的目录管理。目录名称只支持英文、数字、下划线的组合,一个模板对应一个``.html``文件。
支持基本的模板语法,如输出变量、条件判断、循环、包含子模板。[模板语法参考](https://github.com/aui/tmodjs/wiki/模板语法)
> 完全支持 [artTemplate](https://github.com/aui/artTemplate) 的语法
## 编译模板
只需要运行``ali-tmod``这个命令即可,默认配置参数可以满足绝大多数项目。
```
tmod [模板目录] [配置参数]
```
模板目录必须是模板的根目录,若无参数则为默认使用当前工作目录,tmodjs 会监控模板目录修改,每次模板修改都会增量编译。
### 配置参数
* ``--debug`` 输出调试版本
* ``--charset value`` 定义模板编码,默认``utf-8``
* ``--output value`` 定义输出目录,默认``./build``
* ``--type value`` 定义输出模块格式,默认``default``,可选``fmd``、``pure-fmd``、``cmd``、``amd``、``commonjs``
* ``--no-watch`` 关闭模板目录监控
* ``--version`` 显示版本号
* ``--help`` 显示帮助信息
配置参数将会保存在模板目录[配置文件](#配置)中,下次运行无需输入配置参数(``--no-watch`` 与 ``--debug`` 除外)。
#### 示例
```
ali-tmod ./tpl --output ./build
```
## 使用模板
根据编译的``type``的配置不同,会有两种不同使用方式:
### 使用默认的格式
TmodJS 默认将整个目录的模板压缩打包到一个名为 template.js 的脚本中,可直接在页面中使用它:
<script src="tpl/build/template.js"></script>
<script>
var html = template('news/list', _list);
document.getElementById('list').innerHTML = html;
</script>
> template.js 还支持 RequireJS、SeaJS、NodeJS 加载。[示例](http://aui.github.io/tmodjs/test/index.html)
### 指定格式(fmd /amd / cmd / commonjs)
此时每个模板就是一个单独的模块,无需引用 template.js:
```
var render = require('./tpl/build/news/list');
var html = render(_list);
```
> 注意:模板路径不能包含模板后缀名
## 演示
[TmodJS 源码包](https://github.com/aui/tmodjs/archive/master.zip)中``test/tpl``是一个演示项目的前端模板目录,基于默认配置。切换到源码目录后,编译:
```
ali-tmod test/tpl
```
编译完毕后你可以在浏览器中打开 [test/index.html](http://aui.github.io/tmodjs/test/index.html) 查看如何使用编译后的模板。
## 配置
TmodJS 的项目配置文件保存在模板目录的 package.json 文件中:
```
{
"name": "template",
"version": "1.0.0",
"dependencies": {
"tmodjs": "1.0.0"
},
"tmodjs-config": {
"output": "./build",
"charset": "utf-8",
"syntax": "simple",
"helpers": null,
"escape": true,
"compress": true,
"type": "default",
"runtime": "template.js",
"combo": true,
"minify": true,
"cache": false,
"resolve":null
}
}
```
字段 | 类型 | 默认值| 说明
------------ | ------------- | ------------ | ------------
output | String | ``"./build"`` | 编译输出目录设置
charset | String | ``"utf-8"`` | 模板使用的编码(暂时只支持 utf-8)
syntax | String | ``"simple"`` | 定义模板采用哪种语法。可选:``simple``、``native``
helpers | String | ``null`` | 自定义辅助方法路径
escape | Boolean | ``true`` | 是否过滤 XSS。如果后台给出的数据已经进行了 XSS 过滤,就可以关闭模板的过滤以提升模板渲染效率
compress | Boolean | ``true`` | 是否压缩 HTML 多余空白字符
type | String | ``"default"`` | 输出的模块类型,可选:``default``、``fmd``、``pure-fmd``、``cmd``、``amd``、``commonjs``、``customize``
runtime | String | ``"template.js"`` | 设置输出的运行时名称
alias | String | ``null`` | 设置模块依赖的运行时路径(仅针对于非``default``的类型模块配置字段。如果不指定模块内部会自动使用相对 runtime 的路径)
combo | Boolean | ``true`` | 是否合并模板(仅针对于 default 类型的模块)
minify | Boolean | ``true`` | 是否输出为压缩的格式
cache | Boolean | ``true`` | 是否开启编译缓存
resolve | Array | ``null`` | 是否对模块id使用resolve,编译使用``id.replace``方法,参考值``[ "^(.*)","work/$1"]``(仅针对fmd,pure-fmd类型的模块)
## grunt
让 TmodJS 作为 Grunt 的一个插件使用:
```
npm install grunt-tmod --save-dev
```
由[@Jsonzhang](https://github.com/Jsonzhang)开发,项目主页:
<https://github.com/Jsonzhang/grunt-tmod>
## gulp
让 TmodJS 作为 Gulp 的一个插件使用:
```
npm install gulp-tmod --save-dev
```
由[@lichunqiang](https://github.com/lichunqiang)开发,项目主页:
<https://github.com/lichunqiang/gulp-tmod>
## 常见问题
**问**:TmodJS 需要部署到服务器中吗?
> 不需要,这是本地工具,基于 NodeJS 编写是为了实现跨平台。
**问**:如何将每个模板都编译成单独的 amd/cmd 模块输出?
> 指定 type 参数即可,如``--type cmd``则可以让每个模板都支持 RequireJS/SeaJS 调用。
**问**:如何将模板编译成 NodeJS 的模块?
> 指定 type 参数即可,如``--type commonjs``。
**问**:线上运行的模板报错了如何调试?
> 开启 debug 模式编译,如``--debug``,这样会输出调试版本,可以让你快速找到模板运行错误的语句以及数据。
**问**:如何不压缩输出 js?
> 编辑配置文件,设置``"minify": false``。
**问**:如何修改默认的输出目录?
> 指定 output 参数即可,如``--output ../../build``。
**问**:如何让模板访问全局变量?
> 请参考:[辅助方法](https://github.com/aui/tmodjs/wiki/辅助方法)。
**问**:可以使用使用类似 tmpl 那种的 js 原生语法作为模板语法吗?
> 可以。编辑配置文件,设置``"syntax": "native"``即可,目前 TmodJS 默认使用的是 simple 语法。
**问**:如何兼容旧版本 atc 的项目?
> 编辑配置文件,分别设置``"type": "cmd"``、``"syntax": "native"``、``"output": "./"``
**问**:如何迁移原来写在页面中的 artTemplate 模板,改为 TmodJS 这种按按文件存放的方式?
> 请参考:[页面中的模板迁移指南](https://github.com/aui/tmodjs/wiki/页面中的模板迁移指南)。
**问**:我需要手动合并模板,如何让 tmodjs 不合并输出?
> 编辑配置文件,设置``combo:false``。
## 版本更新
- 1.2.1
bugfix: 修复开启 minify 时 报错:
```
Error: Uglification failed.
Path must be a string. Received undefined.
at (node_modules\ali-tmodjs\src\uglify2.js:49:33)
at Tmod._uglify (node_modules\ali-tmodjs\src\tmod.js:760:23)
```
- 1.2.0
增加自定义编译模式
- 1.0.7
增加模块id resolve配置入口
## 授权协议
BSD.