使用新一代js模板引擎NornJ提升React.js开发体验
当前的前端世界中有很多著名的开源javascript模板引擎如Handlebars、Nunjucks、EJS等等,相信很多人对它们都并不陌生。
js模板引擎的现状
通常来讲,这些js模板引擎项目都有一个共同的特性:只专注渲染字符串(html)
早在几年前Backbone等mv*
框架流行的时候,js模板引擎遇到了它们的春天,因为Backbone可以支持选配用户自己喜好的模板,并提供了接入方案。但是在新一代前端mv*
框架盛行的今天,人们更多的关注点在于React的JSX
支持的逻辑何等地强大、Vue的v-show
等指令使用起来多么地方便,而js模板引擎呢?它们似乎只能在Node.js服务器端找到它们的归宿,而且还被React及Vue的SSR(服务端渲染)继续蚕食着仅有的市场。
为什么各种各样的js模板引擎都只专注于渲染html字符串?这或许跟历史原因有关,毕竟5、6年前的时候并没有虚拟dom
,使用jQuery等框架的$('div').html(str)
方法渲染dom是理所当然的事情。
新型js模板引擎
我们不妨试想一下,其实js模板引擎在当前的时代只要也能做到渲染虚拟dom
对象,或许就可以再次找到它们被重用的机会:
+---------------------+
¦ <Template string /> ¦
+---------------------+
|
|
+---------------------+
| render to |
| |
+-------------+ +-------------------+
¦ html string ¦ ¦ React virtual dom ¦
+-------------+ +-------------------+
然而目前有一个新的js模板引擎可以做到上述的同时支持渲染html和React组件,它就是NornJ。
github:https://github.com/joe-sky/nornj
官方文档(github pages):https://joe-sky.github.io/nornj-guide/
官方文档(gitbook):https://joe-sky.gitbooks.io/nornj-guide/
安装
npm install nornj
npm install nornj-react # React开发请一起安装此包
npm install nornj-loader # webpack环境请一起安装此包
在线演示地址
渲染html字符串
渲染React组件
在React开发中的基本使用方法
React在介绍自己时常说JSX是"可选的",但实际上,脱离了JSX的React根本就几乎无法正常地开发。如果有了另一种DSL(js模板引擎)可适配React开发,那么JSX才能真正地成为可选的技术。
NornJ的模板语法在参考自Handlebars
、Nunjucks
、Vue
等多个著名项目的基础上,也有很多自己独特的语法如tagged template string
、自定义语句与运算符
等等,与html+js非常相似可快速上手。需要提一下另一个React
的模板项目react-templates,它是React
生态中唯一一个比较完善的模板项目,但很可惜的是它现在已经几乎不维护了,而且功能非常有限。
每个React组件都须要在render返回组件的标签代码,如在HelloWorld
组件中渲染一个下拉框,用JSX
和NornJ
的语法分别实现:
- JSX
export default class HelloWorld extends Component {
render() {
return (
<div className="hello" style={{ width: 300, height: 200 }}>
<input type="text" />
<select>
{[1, 2, 3].map((item, i) => i > 1
? <option>{item + 1}</option>
: <option>{item}</option>
)}
</select>
</div>
);
}
}
- NornJ
import { template as t } from 'nornj';
import 'nornj-react';
import { Input } from 'antd';
export default class HelloWorld extends Component {
render() {
return t`
<div class="hello" style="width:300px;height:200px;">
<input type="text">
<select>
<#each {1 .. 3}>
<#if {@index > 1}>
<option>{@item + 1}</option>
<#else><option>{@item}</option></#else>
</#if>
</#each>
</select>
</div>
<${Input} placeholder="Basic usage" />
`;
}
}
如上例,这就是NornJ
最基本的使用方法了,开箱即用。它可以使用ES6+
的tagged template literals
语法在js文件中描述模板,模板语法在处理逻辑时的结构比JSX
更加易读,且语法和html更为接近:
- 可以写class替代className。
- style可以使用html中写style属性的方式,当然写对象也同样支持。
- 模板语法提供了
#if
、#each
等扩展标签用于处理逻辑,可替代三目运算符
与数组map方法
。 - input和img等标签支持只写开标签,如
<input type="text">
,JSX中一定要写为<input type="text" />
。 - 可直接在组件的render中返回同一级别的多个标签,外面不用套上数组。
- 双花括号
{{}}
和单花括{}
号语法在React开发中都支持,除特殊场景外依个人喜好而定。 - 模板和JSX一样支持嵌入任意js变量,这当然也包含第三方React组件和JSX变量,
NornJ
模板和JSX是可以共存的!
NornJ
的tagged template literals
语法更多细节请查看官方文档。
上面的例子也可以这样改写:
import nj from 'nornj';
import 'nornj-react';
import { Input } from 'antd';
const tmplFn = nj`
<div class="hello" style="width:300px;height:200px;">
...
</div>
<${Input} placeholder="Basic usage" />
`;
export default class HelloWorld extends Component {
render() {
return tmplFn();
}
}
可以看出,实质上tagged template literals
语法就是创建了一个模板函数,然后再在render中执行了而已。这时不难想到,使用第一种方法将模板函数放到render中执行,这样会不会每次执行render时都进行模板编译(内部涉及各种正则析取)会造成性能下降?并不会,因为NornJ
模板在编译时会进行缓存,只有第一次render时会进行模板编译,之后的每次render就会走缓存了。
另外,NornJ
和JSX
还可以嵌套编写,仅仅在很小的粒度使用NornJ
模板也完全没有问题,具体请见官方文档。
单文件模板
NornJ模板除了可以在js文件中编写之外,还可以编写在单独的模板文件中,用来做组件(或页面)展现层与结构层的分离(具体请参考官方文档)。例如编写一个helloWorld.nj.html
文件:
<template name="partial">
<ant-Input placeholder="Basic usage" value={value} />
</template>
<template name="helloWorld">
<div class={styles.hello}>
<select>
<#each {1 .. 3}>
<#if {@index > 1}>
<option>{@item + 1}</option>
<#else><option>{@item}</option></#else>
</#if>
</#each>
</select>
</div>
<#include name="partial" />
</template>
然后可以在js文件中引入后使用:
import tmpls from './helloWorld.nj.html';
export default class HelloWorld extends Component {
state = {
value: 'test'
};
render() {
return tmpls.helloWorld(this.state, this.props);
}
}
如上,每个*.nj.html
文件内都可以定义一个或多个template
标签。这些template
标签会在引用它的js文件中通过nornj-loader进行解析,生成一个以template
标签的name
属性为key的模板函数集合对象,在各个组件的render中调用它们就会生成相应的React vdom
对象。
针对NornJ
的单文件模板,我们也提供了一些IDE的语法高亮与提示工具。
扩展模板
NornJ与Handlebars
比较类似具有非常强大的可扩展性,#if
、#each
等实际上都是扩展出来的语法,您完全可以自己扩展出#customIf
、#customEach
等新语句。在可扩展性这一点上,不难想到JSX也可以通过babel进行扩展,也可以搞新的语法出来,例如jsx-control-statements。但是babel扩展上手门槛不低,要学各种babel AST的用法,开发一个完美的插件出来似乎并非易事。
由于NornJ
继承于Handlebars
的扩展方式,它内部的每个扩展都可以用一个函数简单地开发出来,例如为NornJ
扩展一个**
运算符,作用是乘方运算:
import nj from 'nornj';
nj.registerFilter('**', (val1, val2) => Math.pow(val1, val2));
然后就可以直接使用了:
<input value="{ 2 ** 10 / 100 }">
当然上述只是个最简单的例子,更多模板扩展描述请参考官方文档。
结合Mobx创建双向数据绑定
利用NornJ的可扩展性,模板语法在理论上可以实现无限的可能性。#mobx-model
是NornJ
实现的一个行内扩展标签(类似于vue及ng的指令),具体用法如下:
import { Component } from 'react';
import { observable } from 'mobx';
import nj from 'nornj';
import 'nornj-react';
import 'nornj-react/mobx';
class TestComponent extends Component {
@observable inputValue = '';
render() {
return nj`<input :#mobx-model="inputValue">`(this);
}
}
#mobx-model
的底层实现方式和Vue的v-model
是比较类似的。React也有其他双向绑定的实现如Mota,但该项目的实现方式是通过高阶组件。利用NornJ
的扩展语法,我们还能实现更多类似于#mobx-model
的扩展功能。
结合React的各种生态
NornJ可以完美结合各种React生态,包括React-Native
、Redux
、React-Router
、Mobx
、Ant Design
等等,它可以和任何已有的React生态共存。
更多详细文档请见官方文档。
适配各种React-Like库
NornJ在理论上可以适配任意React-Like库,包括Preact、inferno、anu、Nerv等。
具体适配方式请见官方文档。
渲染html字符串
NornJ同时还支持渲染html字符串,这和传统的js模板引擎就完全一样了。使用方法和React中几乎完全一样,具体请看这个在线实例:
当然,NornJ
也能够支持Node.js服务器Express
及Koa
等。传统js模板的compile
、render
等方法,NornJ
也支持。
更多细节请见官方文档。
NornJ的未来计划
NornJ在未来我们还有很多可以增强的方面,例如:
- 开发eslint插件
NornJ
目前虽然内部有语法错误警告机制,但只是将错误打印在控制台。对于静态语法错误检测,NornJ
将来有必要开发一个eslint插件。
- 性能持续优化
虽然NornJ
目前的模板渲染效率已然不低(请见模板渲染效率测试),但仍尚有很大的优化空间,会持续进行优化工作。
国际化
对Vue提供适配
NornJ
适配Vue暂时是个设想,理论上是可以实现的。但有几个难题:
- Vue使用的
虚拟dom
对象结构并非React那样简单,它使用类似snabbdom的结构,其中的事件等方法都绑在特殊的对象上。这对NornJ
来说适配起来和React比有一定难度。 - Vue的模板语法已然很好用,虽然
NornJ
可以提供一些自身独特的语法,但是提升开发体验的作用恐怕没有在React中那样明显。
NornJ发展到今天已经拥有了很多强大的功能,日后还会继续完善,欢迎试用。
使用新一代js模板引擎NornJ提升React.js开发体验的更多相关文章
- JS 模板引擎 BaiduTemplate 和 ArtTemplate 对比及应用
最近做项目用了JS模板引擎渲染HTML,JS模板引擎是在去年做项目是了解到的,但一直没有用,只停留在了解层面,直到这次做项目才用到,JS模板引擎用了两个 BaiduTemplate 和 ArtTemp ...
- 掌握js模板引擎
最近要做一个小项目,不管是使用angularjs还是reactjs,都觉得大材小用了.其实我可能只需要引入一个jquery,但想到jquery对dom的操作,对于早已习惯了双向绑定模式的我,何尝不是一 ...
- JS模板引擎 :ArtTemplate (1)
1.为什么需要用到模板引擎 我们在做前端开发的时候,有时候经常需要根据后端返回的json数据,然后来生成html,再显示到页面中去. 例如这样子: var data = [ {text: " ...
- js模板引擎--artTemplate
js模板引擎--artTemplate 以前研究过一段时间的handlebars,但因为其渲染性能略逊于腾讯的artTemplate(在artTemplate的GitHub官网上有推荐的性能测试地址) ...
- JS模板引擎:tppl
全球最快的JS模板引擎:tppl 废话不多说,先上测试: 亲测请访问:[在线测试地址]单次结果不一定准确,请多测几次. tppl 的编译渲染速度是著名的 jQuery 作者 John Resig 开发 ...
- 百度JS模板引擎 baiduTemplate 1.0.6 版
A.baiduTemplate 简介 0.baiduTemplate希望创造一个用户觉得“简单好用”的JS模板引擎 注:等不及可以直接点左侧导航中的”C.使用举例“,demo即刻试用. 1.应用场景: ...
- Epii.js 一个极其简单的Js模板引擎
Epii.js 简约而不简单的Js模板引擎 Epii.js 简约而不简单的JavaScript模板引擎 # 特性 一个轻量级模板引擎,可快速实现数据与ui绑定(数据变动,UI自动变动),快速实现事件绑 ...
- laytpl js模板引擎
laytpl js模板引擎.laytpl是一款非常轻量的JavaScript模板引擎.地址:http://www.layui.com/laytpl/ 用法与handlebar.js类似,但是比较轻量级 ...
- js模板引擎之artTemplate
http://www.cnblogs.com/52fhy/p/5393673.html artTemplate 不支持requre.js,悲剧啊,只能用juicer啊 这个还是比较有名的. 简介: a ...
随机推荐
- Hadoop搭建全程
修改配置文件 cd /etc/sysconfig/network-scripts #进入网络配置目录 dir ifcfg* #找到网卡配置文件 ifc ...
- 实用的HTML优化技巧
如何提升Web页面的性能,很多开发人员从多个方面来下手如JavaScript.图像优化.服务器配置,文件压缩或是调整CSS. 很显然HTML 已经达到了一个瓶颈,尽管它是Web开发 界面必备的核心语言 ...
- 教你如何前后端完全分离(非api、ajax)
我的前后分离,不是api,不是ajax,我这里只讨论html与后端结合 前话 曾经风靡一时的dedecms相信做网站的十有八.九都知道,还有那么一些不是技术出生的人,通过看一下文档,也能访问出网站出来 ...
- leetCode:206 反转链表
206. 反转链表 题目:反转一个单链表. 进阶:链表可以迭代或递归地反转.你能否两个都实现一遍? 非递归代码: class Solution { public ListNode reverseLis ...
- Java路径类问题总结
一.获取路径: 单独的Java类中获得绝对路径根据java.io.File的Doc文挡,可知: 默认情况下new File("/")代表的目录为:System.getPropert ...
- linux常用命令汇总(更新中...)
文本查看与编辑 1.文本编辑命令 vi/vim 2.查看文件内容命令 命令 说明 命令格式 参数 cat 将一个文件的内容连续输出在屏幕上 cat [-option] 文件名 -n:将行号一起显示在 ...
- 笔记:Hibernate 持久化类标注说明
持久化类标注 标注 @Entity:注解声明该类是一个Hibernate的持久化类 标注 @Table:指定该类映射的表 参数 name:指定映射数据库表的名称 参数 uniqueConstraint ...
- Java代理模式之动态代理
动态代理类的源码是程序在运行期间由JVM根据反射等机制动态生成的,所以不存在代理类的字节码文件.代理角色和真实角色的联系在程序运行时确定! Java中有两种动态代理,一种是JDK自带的,另一种的CGL ...
- 继续吐槽在net下没有合适的Disk Cache之使用EhCache
说起缓存,大家可能口若悬河,各种类型的缓存都能一一分析,但在net下找到一款合适的Disk Cache貌似还是有一点难度的. 一:背景 事情是这样的,最近的一个项目中,需要在web端绘制一些报表,因为 ...
- 小白学PYTHON时最容易犯的6个错误,看看你遇到过几个
最近又在跟之前的同学一起学习python,一起进步,发现很多测试同学在初学python的时候很容易犯一些错误,特意总结了一下.其实这些错误不仅是在学python时会碰到,在学习其他语言的时候也同样会碰 ...