art-template icon indicating copy to clipboard operation
art-template copied to clipboard

art-template@4 新特性一览

Open aui opened this issue 7 years ago • 42 comments

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

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

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

art-template@4 主要特性:

高速渲染

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

chart

调试增强

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

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

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

调试日志

v4-debug

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

debug-v3

[email protected] 使用了一点点黑魔法实现了编译调试,这里以后准备在以后分享实现细节。

断点

使用 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>
<% } %>

值得一提的是,[email protected] 兼容了 EJSUnderscoreLoDash 的模板语法,也兼容 [email protected] 语法。

模板继承

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

范例

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 后,将自动应用布局骨架。可以看到,使用模板继承可以节省很多代码量。

自定义语法

[email protected] 支持应用多个模板解析规则,例如让模板引擎支持 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

aui avatar Apr 16 '17 11:04 aui

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

guanMac avatar Apr 16 '17 12:04 guanMac

更新: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

aui avatar Apr 17 '17 00:04 aui

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

jun-lu avatar Apr 18 '17 08:04 jun-lu

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

doukai avatar Apr 18 '17 10:04 doukai

工匠精神~

Janking avatar Apr 18 '17 15:04 Janking

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

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

Archmee avatar Apr 19 '17 10:04 Archmee

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

aui avatar Apr 19 '17 12:04 aui

@aui 那就放心了,thx

Archmee avatar Apr 19 '17 16:04 Archmee

@guanMac [email protected] 已经内置支持 HTML、CSS、JS 压缩,并且是在编译阶段进行压缩的

aui avatar Apr 19 '17 16:04 aui

赞一个

sxei avatar Apr 20 '17 01:04 sxei

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

sandy1890 avatar Apr 20 '17 04:04 sandy1890

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

addcky avatar Apr 21 '17 07:04 addcky

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

aui avatar Apr 21 '17 11:04 aui

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

aui avatar Apr 23 '17 16:04 aui

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

addcky avatar Apr 24 '17 06:04 addcky

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

abangcc avatar Apr 24 '17 06:04 abangcc

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

aui avatar Apr 24 '17 07:04 aui

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

lsycxyj avatar Apr 26 '17 06:04 lsycxyj

使用问题、BUG 等请另提 issues

aui avatar Apr 26 '17 06:04 aui

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

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

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

  • each as 语法不需要 as 了

ming300 avatar Apr 26 '17 08:04 ming300

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

aui avatar Apr 26 '17 10:04 aui

有个略为尴尬的问题。 在已有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' 是没有问题的)

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

guanMac avatar Apr 27 '17 02:04 guanMac

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

aui avatar Apr 27 '17 05:04 aui

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

aui avatar Apr 27 '17 05:04 aui

@hyingreborn https://github.com/aui/art-template#兼容性 在这是有说只兼容IE8+的

Janking avatar Apr 27 '17 07:04 Janking

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

hyingreborn avatar Apr 27 '17 07:04 hyingreborn

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

frank320 avatar Apr 27 '17 07:04 frank320

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

ghost avatar Apr 27 '17 08:04 ghost

不错,竟然更新了

ghost avatar Apr 27 '17 08:04 ghost

竟然更新了!!!

cipchk avatar Apr 27 '17 11:04 cipchk