aui/art-template

art-template@4 新特性一览

aui opened this issue · 42 comments

aui commented

前端技术日新月异,前端字符串模板引擎已经逐步被 DOM 模板引擎所取代,以至于 art-template 一度停止维护。

现在,art-template 重新回归,带来了全新的 v4 版本。v4 对 NodeJS 进行了更好的支持,并且拥有领先的渲染性能,同时带来了全家桶:express-art-templatekoa-art-template

对于浏览器端,art-template@4.0 带来了基于 WebPack 的 art-template-loader,它能更好的支持预编译,生成非常简洁的代码用于浏览器端使用,它完全可取代年久失修的 TmodJS。

art-template@4 主要特性:

高速渲染

毫无疑问,它依然保持了过去的成绩,并且编码函数 $escape() 是过去的 4 倍速度。

chart

调试增强

模板的错误分为两种:一种是运行时错误,一种是编译错误。

运行时错误:模板访问数据的时候出错,如属性不存在等。对于运行的错误,art-template 从第一个版本已经支持。

编译错误:非法模板语法导致的 javascript 解析错误。对于支持 javascript 原生语句的模板引擎来说,未闭合的 javascript 模板语句通常是合法的,如果其中有语法错误,找到它的位置是一件有挑战的事情。art-template@4.0 不但实现了原生 javascript 语法调试,还支持自定义的语法调试。

调试日志

v4-debug

可以看到,日志中直接定位到了模板所在行。而同样的模板,在 v3.0 上的 debug 几乎只能去查找编译后的代码:

debug-v3

art-template@4.0 使用了一点点黑魔法实现了编译调试,这里以后准备在以后分享实现细节。

断点

使用 Webpack Loader 后可以输出 SourceMap,支持在浏览器中对模板进行断点调试:

webpack debug

混合式语法

art-template 从 v3.0 开始默认采用的是简洁语法,相对于 ejs 式的语法,简洁语法优点是利于读写,弊端是逻辑控制非常有限,比如循环控制等。v4.0 同时支持两种语法,在功能与易用性之间取得较好的平衡:

<!--art 语法-->
{{if user}}
  <h2>{{user.name}}</h2>
  <ul>
    {{each user.tags}}
        <li>{{$value}}</li>
    {{/each}}
  </ul>
{{/if}}

<!--ejs 语法-->
<% if (user) { %>
  <h2><%= user.name %></h2>
  <ul>
    <% for(var i = 0; i < user.tags.length; i++){ %>
        <li><%= user.tags[i] %></li>
    <% } %>
  </ul>
<% } %>

值得一提的是,art-template@4.0 兼容了 EJSUnderscoreLoDash 的模板语法,也兼容 art-template@3.0 语法。

模板继承

模板继承允许你构建一个包含你站点共同元素的基本模板“骨架”。

范例

layout.art:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>{{block 'title'}}My Site{{/block}}</title>

    {{block 'head'}}
    <link rel="stylesheet" href="main.css">
    {{/block}}
</head>
<body>
    {{block 'content'}}{{/block}}
</body>
</html>

index.art:

{{extend './layout.art'}}

{{block 'title'}}{{title}}{{/block}}

{{block 'head'}}
    <link rel="stylesheet" href="custom.css">
{{/block}}

{{block 'content'}}
<p>This is just an awesome page.</p>
{{/block}}

渲染 index.art 后,将自动应用布局骨架。可以看到,使用模板继承可以节省很多代码量。

自定义语法

art-template@4.0 支持应用多个模板解析规则,例如让模板引擎支持 ES6 ${name} 模板字符串的解析:

template.defaults.rules.push({
    test: /${([\w\W]*?)}/,
    use: function(match, code) {
        return {
            code: code,
            output: 'escape'
        }
    }
});

内置的两个语法规则也是采用此接口实现,如果不喜欢内置语法可以干掉它们。

关于 4.0 重构

Github 有用户问我为什么突然又开始密集的对 art-template 进行迭代,连周末也没有停歇。我想应该是这两个理由在驱动我:

  1. 我想认真做一件事情。art-template 是一个技术型产品,从代码到技术产品是需要不断磨砺的,我想体验下将一个简单的开源项目做到极致的感觉

  2. 我在开发过程中实践了很多东西,获得满满的成就。至少有:TDD、Istanbul、CI、AST、Token、SourceMap、NodeJS、KOA、Express、Webpack Loader

NPM Version Coverage Status

赞一个!之前一直在用art-template作为web端的模板渲染。
现在有个问题,koa-art-template是否支持在渲染时使用其他插件,包括js混淆压缩、css/html压缩、之类的。

aui commented

更新:v4.2.0 已经实现

@guanMac 有一个压缩器的配置接口 compressor 。配置如下:

/**
 * 压缩 HTML 输出语句
 * @param {string} source 
 */
const compressor = source => {
    return source
        // remove newline / carriage return
        .replace(/\n/g, "")

        // remove whitespace (space and tabs) before tags
        .replace(/[\t ]+\</g, "<")

        // remove whitespace between tags
        .replace(/\>[\t ]+\</g, "><")

        // remove whitespace after tags
        .replace(/\>[\t ]+$/g, ">")

        // remove comments
        .replace(/<!--[\w\W]*?-->/g, "");
};

template.defaults.compressor = compressor;

它是在编译阶段运行的,因此性能很高。因为模板引擎拿到的是 html 片段,因此能力有限:只能做简单空格压缩,无法对 <pre><script> 进行特殊处理。正因为 compressor 不够完美,因此没有内置到默认配置中。

如果要做完善的压缩服务,可能得在运行时进行,在模板引擎输出整个页面后进行处理。例如使用 Koa 的中间件 https://github.com/koajs/html-minifier

刚才帮后端同学调试一个问题,又发现art-template。 上来看看还在持续更新,良心项目啊

请问是什么让楼主回心转意。

工匠精神~

赞一个,我4.11刚下载在自己小项目中使用,当时文档还很简陋,现在已经完全不认识了【摊手】,不过我想知道的是,虽然现在支持requirejs,但是之前的版本支持requirejs吗,是直接当模块引入还是要配置shim?

PS:之前的版本在requirejs中直接引入也是可用的,只是我担心使用方法不对。

aui commented

@Archmee 两个版本都是使用 UMD 规范打包的,可以支持 requirejs

@aui 那就放心了,thx

aui commented

@guanMac art-template@4.2.0 已经内置支持 HTML、CSS、JS 压缩,并且是在编译阶段进行压缩的

sxei commented

赞一个

看到终于支持layout功能了,大赞~~~

@aui 4.1浏览器版本,已经引入es5_shim.js和json2.js,在ie8浏览器下会抛出“缺少标识符”错误,定位在“return e.default”上面。希望能debug?

aui commented

@addcky 抱歉,这里构建比较麻烦。可能暂时无法解决,文档我去掉。你可以采用 v3 版本

aui commented

@addcky 已经兼容 IE8。引入 shims 的 示例

@aui 好哒。持续关注,期待你的作品

“混合式语法” 请问楼主兼容很多语法,是不是会影响性能,能否添加配置项

aui commented

@hbshun 不会影响性能,只在编译阶段运行;配置见文档
https://github.com/aui/art-template#定义语法规则

openTag和closeTag的功能好像没了?搜了一下代码没这个实现了

aui commented

使用问题、BUG 等请另提 issues

可惜有点和旧版本不兼容,

  • 之前3版本的直接输出内容是

{{=value}} 现在 是 {{@value}}

  • each as 语法不需要 as 了
aui commented

这是升级提示,以后会去掉支持

有个略为尴尬的问题。
在已有express项目里面应用art-template,之前已经定义了全局方法,在art中不能应用:

//过去定义了asset的方法给模板应用
var app =new express();
app.locals.asset = function(){ ... };

//如果要在art模板中应用,则须改成
app.set('view options', {
    imports: {
        $asset: �function(){...}
    }
});

上面是简化大部分代码,实际上 asset是外部的模块。
更经常的使用方式是在一个独立的js模块中,设置 app.locals.xxxx = function()
(app.locals.someVal ='xxx' 是没有问题的)

请问如何可以不改变原来的定义方式?

aui commented

@guanMac 直接 imports=app.locals 不行吗?

aui commented

@hyingreborn 你都看文档明确的说明了只支持 IE8 +,为何还要重复的提问呢?

@Janking @aui 抱歉!直接看4.0介绍,没看首页说明了。。。

给作者点个赞 前后端都用过此模板引擎

gulp用gulp-htmlmin插件压缩模版报错,大神能不能告知一下,怎么压缩artTempalte在使用gulp的情况下,谢谢

不错,竟然更新了

竟然更新了!!!

居然更新了,终于有layout功能了~

支持支持!越来越强大了,不过建议简化下界定符的配置,还是比较喜欢曾今的openTag, closeTag配置。

Lee66 commented

支持一下,这次更新很不错的

npm install art-template 得到的版本3.1.3,不是4+版本

aui commented

@skycai 检查下 package.json 的依赖

喜出望外哦,偶然发现更新了,,,,我准备把项目里tmpl从v3升级到V4。不过其实v3已经很轻巧实用了,够简洁

anota commented

赞一个 从 2.0一直用 竟然意外的更新了 就想要一个 纯净的模板引擎

期待 art-template@4.0 使用了一点点黑魔法实现了编译调试,这里以后准备在以后分享实现细节。这块儿的分享。

前端部分使用的tmod,看到art-template支持node,使用了3.0.3的版本。
依稀还记得之前if/else if/else if/else 好像是有些问题。
现在新版的layout绝对是很大一提升~

已经不记得之前用过的artTemplate是哪一版了但是觉得用着很顺手,后来一段时间还在用。现在刚到出了Node端的引擎,真的很方便。只是目前IDE还不支持高亮和格式化,小小不方便不过不是大问题。

另外,请问一下,我想同时在一个模板里,既使用node端模板,又在这个模板里面使用web版的template-web(因为页面中之后肯定还会有异步操作)。现在试了下面的代码,但是无法加载出来 ,template方法出来的内容是空字符串,请问是我使用的方法不对吗?谢谢。
`<script id="tpl-user" type="text/html">

{{user1.name}}


</script>

<script> var temp = template('tpl-user', {user1: {name: 'test'}}); $('#content').append(temp); </script>`

又看了一下生成网页的源代码,发现模板里面的变量应该是被服务器在一开始渲染整个模板页面的时候一起编译了。。。没有当作生成后的html页面内容中的模板变量,留在后面再使用。。。。请问有什么办法让两者共存吗?

原来之前有过类似的问题,不过是去年了~~ #276

aui commented

其他问题请新建 issues