juicer

article/2025/9/11 21:05:03

UPDATE: juicer-0.3.1-dev published @ github.com.

让我们从一段代码说起,假设有一段这样的JSON数据:

var json={name:"流火",blog:"ued.taobao.org"
};

我们需要根据这段JSON生成这样的HTML代码:

流火 (blog: ued.taobao.org)

传统的Javascript代码一定是这个样子:

var html;
html=''+json.name+' (blog: '+json.blog+')';

不言而喻,这样的代码混杂了html结构和代码逻辑,而且代码不具可读性,不便于后期维护,于是便有了这样一个函数:

function sub(str,data) {return str.replace(/{(.*?)}/igm,function($,$1) {return data[$1]?data[$1]:$;});
}

有了这个函数,我们拼接字符串的工作就可以简化为:

var tpl='{name} (blog: {blog})';
var html=sub(tpl,json);

看到这里,不用我多说,我想通过这个例子直观的展现出前端模板引擎的好处所在,这么做能够完全剥离html和代码逻辑,便于多人协作和后期的代码维护。当然,当我们的业务逻辑需要对数据源进行循环遍历,if判断等的时候,这个简明的函数很显然并不能满足我们的需求,于是便有了如今这市面上众多的模板引擎,诸如Mustache, jQuery tmpl, Kissy template, ejs, doT, nTenjin, etc.

“如无必要,勿增实体。” 这是著名的奥卡姆剃须刀法则,简单的说就是避免重复造轮子。那么就会有童鞋质疑,既然已然有这么多现成的东西可用,为什么还要重新打造一个呢?

我个人认为一个完善的模板引擎应该兼顾这几点:

  • 语法简明
  • 执行效率高
  • 安全性
  • 错误处理机制
  • 多语言通用性

而市面上现有的模板引擎没有做到兼顾以上几点,比如Mustache支持多种语言,通用性不错,不过性能稍差,而且语法不支持高级特性,例如遍历的时候无法做if判断,也无法获得index索引值,jQuery tmpl依赖jQuery,缺乏可移植性,Kissy template虽然依赖Kissy, 不过性能和语法都值得推荐,doT/nTenjin 性能和灵活性都很不错,但是语法需要用原生的js来写,写好的模板代码可读性稍差。

鱼和熊掌不可兼得,语法的处理,安全性的输出过滤和错误处理机制的引入在一定程度上都会或多或少降低模板引擎的性能,因此就需要我们权衡。Juicer 在实现上首先将性能看做第一个重要的指标,毕竟性能好坏直接影响用户的感知,同时兼顾了安全性和错误处理机制(即便这样会导致性能的略微下降)。

首先来看下jsperf上同几个主流模板引擎的性能对比。

可以看到,性能上比传统模板引擎均有提升,下边的介绍主要从语法、安全性和错误处理,以及如何使用这几个方面介绍下Juicer.

a. 语法

  • 循环 {@each}…{@/each}
  • 判断 {@if}…{@else if}…{@else}…{@/if}
  • 变量(支持函数)${varname|function}
  • 注释 {# comment here}

详细的语法请参考 Juicer Docs.

b. 安全性

安全性,简单地说就是对输出数据在输出前进行一次转义过滤,避免XSS这样的脚本注入攻击,简单扫下盲,举个XSS的例子。

var json={output:'alert("XSS");'
};

如果JSON数据是第三方接口返回或者含有用户输入(像BBS、评价)的内容,我们如果赤裸裸的将output写到页面上就会执行恶意的js代码,所以Juicer默认是对数据输出做了安全转义的,当然如果不想被转义,可以使用$${varname}。

juicer.to_html('${output}',json); 
//输出:<script>alert("XSS");</script>juicer.to_html('$${output}',json); 
//输出:<script>alert("XSS");</script>

c. 错误处理

如果没有错误处理,当模板引擎编译(Compile)或者渲染(Render)出错时候就会引起后续js代码停止执行,可想而知,如果因为一个逗号或者JSON数据的偶发错误导致整个页面挂掉,是我们不能接受的。但是Juicer在遇到这些错误的时候不会影响后续代码的执行,只会在控制台打出一句警告(Warn)告知开发者模板解析出现错误。

juicer.to_html('${varname,,,,,,,}',json);
alert('hello, juicer!');

执行上边的代码就会看到控制台打出的“Juicer Compile Exception: Unexpected token ,”,但是不会因为错误导致后续的alert被阻塞掉。

实现原理

Juicer对一个模板的编译和渲染的过程主要有以下几个步骤:

  • 1、对模板代码进行语法分析
  • 2、分析后生成原生的Javascript代码字符串
  • 3、将生成的代码转为可重用的Function (Compiled Template)
var json={list:[{name:"benben"},{name:"liuhuo"}]
};
juicer.set('errorhandling',false);//pre-set option
var tpl='{@each list as value,key}$${value.name}{@/each}';
var compiled_tpl=juicer(tpl);

我们通过compiled_tpl.render.toString()看下编译后的代码:

function anonymous(data) {var data = data || {};var out = '';out += '';for (var i0 = 0, l = data.list.length; i0 < l; i0++) {var value = data.list[i0];var key = i0;out += '';out += ((value.name));out += '';}out += '';return out;
}

是不是已经明白了Juicer的原理?这个编译后的函数就会每次帮我们完成从数据到html代码的拼装操作。

这里有几点优化的地方值得分享下:

  • 1、using += instead of array.push
  • 2、avoid using with {}
  • 3、cache the compiled template (function)

这几点优化在大数据量循环渲染时候性能提升显著,不过正因为放弃了with{}语句,所以Juicer会在编译函数之前对模板进行词法分析,将用到的变量实现声明,这样就能避免JSON数据外层必须指定“data.”前缀,如果你觉得这点性能的提升不重要,也可以在options中指定loose:false(禁用松散模式),这样就可以不省去data. 前缀,这样做的好处就是性能会更好一些。

最后介绍下Options配置项,左侧为参数默认值。

{cache:true/false,loose:true/false,strip:true/false,errorhandling:true/false
}

cache默认为true,即同一个模板编译后是否被juicer缓存,也就是说如果缓存开启的情况下,同一个模板第一次编译后,为了缩短耗时提升性能,后续不会再次执行编译的操作而是直接从缓存中去取编译好的模板函数。

Juicer的API. Juicer有两种使用方法,一种是通过

juicer(tpl,data);
--- 或者 ---
juicer.to_html(tpl,data);

直接根据提供的数据将模板转为html代码,另一种是通过compile方法先将模板编译好,在需要的时候再对模板进行数据的Render操作:

var compiled_tpl=juicer(tpl);
compiled_tpl.render(data);
--- 或者 ---
var compiled_tpl=juicer.compile(tpl);
compiled_tpl.render(data);

最后附上Juicer的项目地址,上边有详细的文档和Demo代码。
http://juicer.name


http://chatgpt.dhexx.cn/article/pya98DOF.shtml

相关文章

Juicer软件的安装详解

欢迎关注”生信修炼手册”! 软件安装是生物信息实战中最基础的技能之一&#xff0c;只有确保软件安装无误&#xff0c;后续使用起来才会得心应手&#xff0c;不会有很多的bug。juicer软件提供了Hi-C数据一键化分析的pipeline, 这样高度的封装使得用户操作起来更加简便&#xff…

Juicer实战详解

欢迎关注”生信修炼手册”! Juicer软件的运行是非常简单的&#xff0c;只需要设置几个参数就可以了&#xff0c;本文利用官网的小的测试测试数据集来展示该软件的基本用法。 1. 下载测试数据 从以下链接下载测试数据集 https://github.com/aidenlab/juicer/wiki/Running-Juicer…

Juicer: 辅助基因组组装

Juicer: 辅助基因组组装 Juicer 导读 本文主要对处理HiC数据的Juicer程序进行一个简短的介绍&#xff0c;并展示如何利用Juicer进行基因组组装中染色体挂载的第一步。 1. 介绍 算法介绍 Juicer[1] 是一款能够提供一键式分析Loop-Resolution的程序。 特点 只需一次单击&#xff…

如何同步数据库数据

第一步 打开mysql的客户端 这里使用navicat&#xff0c;连接数据库&#xff0c;等到navicat主页面&#xff0c;双击需要操作的数据库连接 第二步 登录到数据库主页面后&#xff0c;点击左侧的数据库链接&#xff0c;打开数据库&#xff0c;可以看到可以操作的所有数据库 第三…

Logstash数据同步

Logstash 是 Elastic 技术栈中的一个技术&#xff0c;它是一个数据采集引擎&#xff0c;可以从数据库采集数据到 ES 中。可以通过设置 自增 ID 主键 或 更新时间 来控制数据的自动同步&#xff1a; 自增 ID 主键&#xff1a;Logstatsh 会有定时任务&#xff0c;如果发现有主键…

数据同步-数据库间的双向同步

当业务侧需要MongoDB降配、活动数据迁移时都需要应用切换数据库实例进行发版&#xff0c;发版过程中需最大程度保证新旧数据库数据一致&#xff0c;这就涉及到了一种同步技术-数据双向同步。在同步过程中遇到了一些可能会产生问题或引发思考的点&#xff0c;希望利用这篇文档进…

什么是数据实时同步,为什么数据实时同步很重要

随着云成为前所未有的数据供应渠道&#xff0c;数据准确性、一致性和隐私性的重要性与日俱增。看似轻微的数据错误或故障可能会产生重大负面影响。但是&#xff0c;​对数据进行排序并将其与现有​&#xff0c;然后定期解析数据实时同步&#xff0c;同时保持数据完整性&#xf…

数据同步工具的研究(实时)

数据同步工具的研究&#xff08;实时同步&#xff09;&#xff1a; FlinkCDC、Canal、Maxwell、Debezium ——2023年01月17日 ——Yahui Di 1. 常用CDC方案比较 2. FlinkCDC FlinkCDC的简介&#xff1a; Flink CDC 连接器是 Apache Flink 的一组源连接器&#xff0c;使用变…

聊聊数据同步

一、简述 数据同步&#xff0c;这是一个很宽泛的概念&#xff0c;在互联网或者传统软件公司&#xff0c;一定会遇到数据同步的场景。数据同步一般会遇到的问题诸如同步时延、数据一致性、性能低、强依赖于中间件、失败后无法补偿等。本文笔者试图简要总结下常见的数据同步场景&…

大数据的数据同步方式

一、全量覆盖 不需要分区&#xff0c;同步时直接覆盖插入。适用于数据不会有任何新增和变化的情况。比如地区、时间、性别等维度数据&#xff0c;不会变更或变更不影响业务&#xff0c;可以只保留最新值 二、仅新增同步 每天新增一个日期分区&#xff0c;同步并存储当天的新…

DataLink 数据同步平台

文章目录 一、数据同步平台概述核心能力工作原理详细流程 二、快速接入部署中间件程序配置创建数据库表启动应用注意事项 三、扩展&#xff1a;四种 CDC 方案比较优劣 一、数据同步平台 在项目开发中&#xff0c;经常需要将数据库数据同步到 ES、Redis 等其他平台&#xff0c;通…

数据同步之全量同步与增量同步

一、什么是数据同步 业务数据是数据仓库的重要数据来源&#xff0c;我们需要每日定时从业务数据库中抽取数据&#xff0c;传输到数据仓库中&#xff0c;之后再对数据进行分析统计。 为保证统计结果的正确性&#xff0c;需要保证数据仓库中的数据与业务数据库是同步的&#xff0…

你了解数据同步吗?

1.写在前面 本篇博客参考《操作系统实战 45 讲》 上篇博客主要介绍的是程序放在什么地方&#xff0c;开发操作系统要了解的最核心的硬件——CPU、MMU、Cache、内存&#xff0c;知道了它们的工作原理。在程序运行中&#xff0c;它们起到了至关重要的作用。 在开发我们自己的操…

数据库同步有哪些方式?【怎么保障目标和源数据一致性】

文章目录 摘要一、几种主流的数据库同步方式二、架构及工作原理三、全量同步和实时增量同步机制四、源和目标五、举例&#xff1a;Oracle 数据实时同步到 Elasticsearch六、目标和源数据一致性七、异构数据类型转换八、总结 摘要 数据库同步有3大难题&#xff1a; 1是如何保障…

数据技术篇之数据同步

第3章 数据同步 1.数据同步基础 直连同步 &#xff08;1&#xff09;什么是直连同步&#xff1f;直连同步是指通过定义好的规范接口 API 和基于动态链接库的方式直接连接业务库&#xff0c;如 ODBC/JDBC 等规定了统 一规范的标准接口&#xff0c;不同的数据库基于这套标准接口…

聊聊数据同步方案

文章目录 常用的数据同步方案数据库迁移场景数据同步场景应用代码中同步定时任务同步通过MQ实现同步通过CDC实现实时同步 CDC&#xff08;change data capture&#xff0c;数据变更抓取&#xff09;Canal基于日志增量订阅&消费支持的业务工作原理Mysql主备复制实现Canal架构…

大数据之路——数据同步

三、数据技术篇—— 数据同步 3.1 数据同步基础 3.1.1 直连同步3.1.2 数据文件同步3.1.3 数据库日志解析同步 3.2 数据仓库同步方式3.2.1 批量数据同步3.2.2 实时数据同步 3.3 同步遇到的问题3.3.1 分库分表3.3.2 增量全量同步的合并3.3.3 数据漂移的处理 有多种不同应用场景&…

关于数据同步的几种实现

关于数据同步的几种实现 概述 关于数据同步主要有两个层面的同步&#xff0c;一是通过后台程序编码实现数据同步&#xff0c;二是直接作用于数据库&#xff0c;在数据库层面实现数据的同步。通过程序编码实现数据同步&#xff0c;其主要的实现思路很容易理解&#xff0c;即有…

数据同步技术

本次旨在分享数据同步技术的相关知识点&#xff0c;包括数据同步概述、数据同步工具、数据库、数据同步到大数据平台。 首先来介绍一下数据同步的概念&#xff1a; 数据同步是为保持数据源与目的地数据一致性而进行的数据传输、处理的过程。 数据同步的场景&#xff1a; 1、主…

几种常见的数据同步方式

数据仓库的特性之一是集成&#xff0c;即首先把未经过加工处理的、不同来源的、不同形式的数据同步到ODS层&#xff0c;一般情况下&#xff0c;这些ODS层数据包括日志数据和业务DB数据。对于业务DB数据而言(比如存储在MySQL中)&#xff0c;将数据采集并导入到数仓中(通常是Hive…