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

[激灵] 可能是世界上最小的 字符串模板库 了~

  •  2
     
  •   50vip · 2019-12-18 09:53:29 +08:00 · 4869 次点击
    这是一个创建于 1802 天前的主题,其中的信息可能已经有所发展或是发生改变。

    仓库地址https://github.com/hustcc/tplv 请勿用于生产环境,写本地工具之类的可以试试。

    要什么仓库地址,就下面 8 行代码。

    /**
     * nano tpl library
     * @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 的语法。

    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)); // will got `Hangzhou, 1200(13% | Top 3)`
    
    19 条回复    2019-12-20 13:09:47 +08:00
    doublleft
        1
    doublleft  
       2019-12-18 10:13:09 +08:00
    挺好玩的,可以做个 benchmark
    fliu2476
        2
    fliu2476  
       2019-12-18 10:16:42 +08:00 via iPhone
    有点意思
    50vip
        3
    50vip  
    OP
       2019-12-18 10:30:41 +08:00
    @doublleft benchmark 如果在 new Function 哪里做一个 cache,肯定是无敌的。否则估计是中上等吧~
    wenzichel
        4
    wenzichel  
       2019-12-18 10:49:36 +08:00
    之前保存着一份用正则实现的,应该更简洁一些,不过效率上没有比较哪个更好,而且不能像你这个取数组或者 json 格式里的值

    ```javascript
    const render = function(template, data) {
    return template.replace(/\${(.+?)}/g, ($1, $2) => {
    const key = $2.trim();
    if (data.hasOwnProperty(key)) {
    return data[key];
    }
    return $1;
    })
    }
    ```
    50vip
        5
    50vip  
    OP
       2019-12-18 13:07:37 +08:00
    @wenzichel 正则实现,还有一个就是要去学习语法,tplv 的语法就是 es6 string 模板的语法。
    zrt
        6
    zrt  
       2019-12-18 13:11:24 +08:00
    will got ?
    50vip
        7
    50vip  
    OP
       2019-12-18 16:40:47 +08:00 via iPhone
    @zrt 感觉我英语能力着急…

    xxx will be got

    will get xx

    来 pr😂
    optional
        8
    optional  
       2019-12-18 18:10:03 +08:00
    至少套个 vm2 吧,,,
    50vip
        9
    50vip  
    OP
       2019-12-18 19:00:33 +08:00
    @optional 什么意思~
    xiri
        10
    xiri  
       2019-12-18 19:15:52 +08:00
    最后一句
    render(template, data));
    是多打了一个括号吗
    50vip
        11
    50vip  
    OP
       2019-12-18 21:46:35 +08:00
    @xiri o,确实是的~
    myqoo
        12
    myqoo  
       2019-12-19 15:06:45 +08:00
    @50vip 有个黑科技可以不用 eval/Function 也能生成高性能模板,并且生成速度更快。而且不受 csp unsafa-eval 影响,小程序里也可以用。
    50vip
        13
    50vip  
    OP
       2019-12-19 19:05:36 +08:00
    @myqoo 你到是说啊~^_^
    myqoo
        14
    myqoo  
       2019-12-19 21:10:07 +08:00
    @myqoo 原理有点复杂,几行代码实现不了,几句话也说不清。大致思路:函数柯里化。返回预制的闭包。
    50vip
        15
    50vip  
    OP
       2019-12-20 09:12:11 +08:00 via iPhone
    @myqoo 不信能做到😏
    doublleft
        16
    doublleft  
       2019-12-20 10:22:29 +08:00
    @50vip #3 new Function 做个闭包 看看能不能缓存函数
    forbreak
        17
    forbreak  
       2019-12-20 10:38:27 +08:00
    new Function 和 eval 那个效率高呢?我之前也用过类似的方式来解析模板,使用的 eval 处理的。
    50vip
        18
    50vip  
    OP
       2019-12-20 13:03:36 +08:00
    @doublleft 加个全局缓存,又感觉会产生内存问题,最好是一个 lru 缓存,但是这样,缓存代码都比模板代码多了,哈哈~好囧~
    50vip
        19
    50vip  
    OP
       2019-12-20 13:09:47 +08:00
    @forbreak 可以 benchmark 试试,应该差不太多吧。eval 稍微快一点。https://atool.vip/#/perf

    ![image.png]( https://i.loli.net/2019/12/20/apRzE7ZcXuDLsmj.png)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   924 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 21:20 · PVG 05:20 · LAX 13:20 · JFK 16:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.