V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
50vip
V2EX  ›  分享创造

面试:如何实现一个模板引擎?

  •  
  •   50vip · 2020-03-23 11:10:24 +08:00 · 3011 次点击
    这是一个创建于 1466 天前的主题,其中的信息可能已经有所发展或是发生改变。

    面试笔试经常会遇到吧?笔试面试一般遇到也不会要求特别高,一般可能想考查的是正则这个点。

    下次遇到,可以看看下面这个轮子 tplv(不用 star,因为这不是重点,重点在最后),应该是一个比较独特的思路(也算抖机灵吧)。

    使用示例

    具体使用方式直接看 README 吧,和其他简单的模板引擎,没有什么很大区别。来一个简单的例子:

    import { render } from 'tplv';
    
    const template = '${ name }, ${value}(${percent} | Top ${array[2]})';
    
    const data = {
      name: 'Hangzhou',
      value: 1200,
      percent: '13%',
      array: [1, 2, 3, 4]
    };
    
    render(template, data); // `Hangzhou, 1200(13% | Top 3)` will be got
    

    原理

    核心代码如下(真正的 7 行代码):

    /**
     * tplv render
     * @param template
     * @param data
     */
    export default function(template: string, data: object): string {
      const ks = Object.keys(data);
      const vs = ks.map((k: any) => data[k]);
    
      const t = `return \`${template}\``;
      const f = new Function(...ks, t);
    
      return f(...vs);
    }
    

    原理是利用 ES6 string template 语法,所以模板语法和 JS 语法一模一样,自带 JS 的所有数据处理能力。

    优势

    这么实现的优势在于:

    1. 小,极简
    2. 模板语法不用学习,天然就会
    3. 自带 JS 的所有数据处理能力(就是写 JS 代码)

    至于劣势或者缺点,自己想一想吧,哈哈。

    性能

    性能测试结果如下:

    我承认,这样的代码去和其他的成熟的模板引擎比较性能,就是耍流氓。

    兼容

    因为 ES6 语法存在浏览器兼容问题,所以请勿用于有浏览器兼容要求的生产环境。但是在 node 端或者本地工具产品中可以放心大胆的使用。ES6 string template 兼容性如下:

    当然,如果你的用户浏览器版本定位很高,那么大可放心使用。毕竟是 JS 语法,能有什么稀奇 bug 能那么幸运被你遇到?

    重点 & 结论

    我们是蚂蚁金服大数据部的前端团队,把控整个蚂蚁的所有数据,贯穿从业务中获取数据,最终到让数据服务业务整个流程中。

    业务上,我们会负责蚂蚁金服几十个数据产品研发迭代。 技术上,我们重点维护交叉表、探索分析画布、编辑器等技术产品,深度参入 AntV G2 栈、G6 栈的开发。

    ...

    更多信息可以加我 wx 私聊,给简历我们做同事,不给简历,我们做朋友。

    投递简历请注明来源于这篇文章,我们就不笔试和面试这一题。

    第 1 条附言  ·  2020-03-23 12:57:51 +08:00

    微信二维码挂了, 重发。

    wx

    第 2 条附言  ·  2020-03-24 13:28:39 +08:00

    是不然发微信吗?

    自己转码一下:和谐民主和谐和谐和谐文明和谐法治和谐公正和谐爱国和谐民主和谐富强和谐敬业和谐爱国和谐法治

    核心价值观解码: https://atool.vip/corevalue/

    10 条回复    2020-03-23 15:57:12 +08:00
    crackhopper
        1
    crackhopper  
       2020-03-23 11:23:52 +08:00
    我还以为 tokenizer+parser 之类的方式呢。目前看起来只能变量替换以及替换的时候做一点 js 计算。模板循环和分支之类的会比较麻烦,需要模板套模板?
    kamilic
        2
    kamilic  
       2020-03-23 12:03:23 +08:00
    可以考虑用 lit-html 啊,也是差不多的书写方式。
    但是他们有类似 v-dom diff 和 patch 的效果(虽然内部实现不是 vdom )
    也挺厉害的
    azh7138m
        3
    azh7138m  
       2020-03-23 12:40:43 +08:00
    我选 https://github.com/developit/htm
    模板引擎自带 xss,安全团队不把你按在地上摩擦?
    50vip
        4
    50vip  
    OP
       2020-03-23 12:52:31 +08:00
    @azh7138m 所以说是玩具,哈哈~重点在于有兴趣加微信~
    50vip
        5
    50vip  
    OP
       2020-03-23 12:52:58 +08:00
    @crackhopper 低级轮子~重点是有兴趣,加微信~
    50vip
        6
    50vip  
    OP
       2020-03-23 12:58:54 +08:00
    @azh7138m 而且 html 已经不算 模板的范畴了,哈哈~
    50vip
        7
    50vip  
    OP
       2020-03-23 13:07:55 +08:00
    @kamilic lit-html 和 @azh7138m 使用 htm 一样,可能都不属于模板引擎的范畴。

    关于安全,大部分的轻量引擎,都不会去考虑 xss,业务自己在事情前使用 xss 转移的模块自行处理。
    azh7138m
        8
    azh7138m  
       2020-03-23 14:00:00 +08:00 via Android
    我 htm 和 HTML 有什么关系
    htm 也算是 jsx 实现的变种
    另外 CSP 下也没有 new Function 给你用
    lzuntalented
        9
    lzuntalented  
       2020-03-23 15:23:24 +08:00
    想体验`易语言`式写 html 模板吗
    请看: https://github.com/lzuntalented/lzCustomWriteHtml
    [捂脸][逃跑]
    50vip
        10
    50vip  
    OP
       2020-03-23 15:57:12 +08:00
    @lzuntalented 666,可以转成文言文~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1039 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:36 · PVG 06:36 · LAX 15:36 · JFK 18:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.