Mustache.js: Mustache.parse() 上的自定义分隔符自 2.3.1 起不起作用

创建于 2018-08-09  ·  16评论  ·  资料来源: janl/mustache.js

由于版本 2.3.1自定义分隔符显然不再适用于Mustache.parse() 。 请参阅以下示例:

  • 2.3.0,工作,值被插入: https ://codepen.io/mbodala/pen/vaQPxK
  • 2.3.1:损坏,未插入值: https ://codepen.io/mbodala/pen/NBEJjX

这很可能与#663 及其修复有关。 请注意,我可以通过使用较新的Mustache.tags = [...]来恢复它: https ://codepen.io/mbrodala/pen/QBJoOx

你能看看这个吗?

所有16条评论

非常感谢@mbrodala的报告,非常感谢那些代码笔!

@mbodala感谢您的代码笔。
我想知道这里是不是有什么误会。

643 和 #664 修复了我在 #617 中报告的错误,该测试说明了这一点,该测试伴随 #643 :

  describe('when parsing a template with tags specified followed by the same template with different tags specified', function() {
     it('returns different tokens for the latter parse', function() {
       var template = "(foo)[bar]";
       var parsedWithParens = Mustache.parse(template, ['(', ')']);
       var parsedWithBrackets = Mustache.parse(template, ['[', ']']);
       assert.notDeepEqual(parsedWithBrackets, parsedWithParens);
     });
   });

parse函数仅使用template作为缓存键进行缓存,因此下次使用parse解析该模板时,它将返回完全相同的标记,甚至如果指定的tags不同。

tags是一个可选参数,当它被省略时,它会回退到mustache.tags ,默认['{{', '}}'] 。 回退mustache.tags用作缓存键的一部分。

我想我知道关于错误修复和期望的情况,我将尝试通过它,我将使用 codepen 作为示例。

v2.3.0

Mustache.parse(template, ['[[', ']]']);

在 2.3.0 中,这指示 Mustache 解析template ,使用['[[', ']]']作为标签。 Mustache 这样做并返回正确的结果,但仅使用template缓存调用。 请参阅[email protected]的第 447-450 行:

    if (tokens == null)
       tokens = cache[template] = parseTemplate(template, tags);

codepen 中的下一个调用是:

var output = Mustache.render(
  template,
...

render不接受tags参数,因此不将 1 传递给parse ,因此当render被调用时, parse使用mustache.tags作为它的标签。 因此,当调用render时,它实际上是在告诉parse ,“请解析template并隐式使用['{{', '}}']作为tags 。” parse实际上做了错误的事情,并且完全忽略了tagsmustache.tags进行缓存查找。 它碰巧返回了用[['[', ']']]解析的模板的结果,但这仅仅是因为在整个程序中为templateparse的第一次调用是用['[[', ']']]进行的tags

v2.3.1

Mustache.parse(template, ['[[', ']]']);

解析结果使用templatetags进行缓存,即['[[', ']]']作为 cacheKey。

下一个电话:

var output = Mustache.render(
  template,
...

render调用parse ,传递template但省略tags 。 因此parsetags回退到mustache.tags ,这仍然是默认的['{{', '}}']parsetemplate['{{', '}}']的缓存键进行缓存查找,并导致缓存未命中,正如预期的那样,因为尚未调用parse使用template和标签的组合。 因此,它使用['{{', '}}']解析template #$ 。

我相信 v2.3.1 表现出正确的行为。 如果我们要稍微更改https://codepen.io/mbodala/pen/QBJoOx中的 codepen 并针对 v2.3.0 运行它:

var template = "[[item.title]] [[item.value]]";
Mustache.parse(template, ['[[', ']]']);
var output = Mustache.render(
  template,
  {
    item: {
      title: "TEST",
      value: 1
    }
  }
);
alert(output);

输出是[[item.title]] [[item.value]] ,这不是预期的。

我可以看到https://codepen.io/mbodala/pen/NBEJjX中的行为可能令人惊讶,因为Mustache.parseMustache.render调用彼此相邻,而一个可能不会甚至意识到Mustache.parse甚至需要tags参数。 (为什么Mustache.parse甚至需要一个tags参数?它从未在mustache.js的任何地方使用过—— parse只是在内部默认为mustache.tags 。 ..)

如果行为的改变确实违背了错误修复版本的期望,那么我不确定该怎么做。 一种可能性是发布另一个修复了 #664 的错误修复版本,这实际上删除了所有缓存行为(假设在 #643 中,所有缓存查找都将丢失)。 然后我们可以将#664 放回下一个主要版本。 另一种可能性是在错误修复版本中删除所有缓存(而不是发布具有非功能缓存的mustache.js ),然后将所有缓存放回下一个主要修订版中。 前一个选项可能风险较小(代码更改量最少),但后一个选项可能更“正确”。 @phillipj 的想法?

非常感谢从我的 POV 中完全理解的详细研究。

我根本不介意更改,但考虑到不可能将tags传递给Mustache.render()以确保缓存命中并且Mustache.parse()被宣传为缓存template (这里没有提到tags )我想知道这是否真的应该恢复。

如果我们假设使用一组自定义的tags调用Mustache.parse ,我们还可以假设template使用这些分隔符(顺便说一句,“标签”与“分隔符”应该是也清理了)。 之后,我们可以假设对Mustache.render的调用预计会起作用,无论给定的template是如何以及是否已经被缓存,以及如果是这种情况,它是如何编译的。 现在,如果使用自定义tags ,则不能保证这一点。

@mbodala是的,这是有道理的,尽管Mustache.parse(template, ['[[', ']]']);后跟Mustache.parse(template, ['((', '))']);给出完全相同的结果仍然是出乎意料的。

这是一个稻草人解决方案/妥协(“稻草人”,因为我不喜欢它,但值得集思广益)。 我们可以单独针对template和带有标签的template parse $。 当parse被指定tags调用时,它会针对templatetags进行查找。 当我们调用render时,它调用parse而没有tags ,然后我们只针对template进行查找。 想法?

听起来不错,基本上是,但会在保持修复完好无损的同时解决这个问题。 从我的 POV 可以。

@mbodala是您不能将tags传递给render的核心问题? 我们也可以在 $ render中添加一个tags参数。

@petrkoutnysw这大致是您遇到的问题吗?

这至少是parse()render()之间的不一致。 如果我们确实可以将自定义标签传递给render() ,我们甚至不会使用parse() 。 现在有了适当的缓存,这变得更加明显。

+1 用于向 render() 添加 tags 参数以消除很多混乱——我们也被这个变化所吸引,链接 b/w 解析和渲染总是看起来比必要的更神奇。

好的,那么我们如何在错误修复版本中禁用缓存,以修复当前问题并遵守语义版本控制,并在下一个主要版本的render方法中重新引入它和tags ? (同样,我不是我提出的稻草人解决方案的忠实粉丝。)

非常感谢@raymond-lam 的彻底演练!

我倾向于建议的错误修复版本,主要是因为 semver 问题和项目的这种行为变化是出乎意料的,因此可能会对野外项目造成严重破坏。

在计划的下一个主要版本中再次重新引入缓存行为,我们可以在发行说明中包含迁移说明。

@phillipj我已经发布了拉取请求#670,它回滚了#643 和#664。 为了降低风险,与其一起禁用缓存,不如简单地回到 v2.3.0 行为(在错误修复版本中)对于 Mustache v2.xx 的依赖者来说似乎是最安全的,我将发出另一个拉取请求以在主要版本中重新引入。

@phillipj #671 重新引入缓存修复,等待主要版本。

创建问题 #672 以解决将tags添加到 `render.

非常感谢您调查和解决这个问题,你们摇滚。 👍

向@raymond-lam 致敬! 还要感谢您,这对我们了解野外何时发生意外变化至关重要。

v2.3.2已经发布🚀

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

barbalex picture barbalex  ·  5评论

ForbesLindesay picture ForbesLindesay  ·  14评论

kuldeepdhaka picture kuldeepdhaka  ·  9评论

chlab picture chlab  ·  11评论

rlightner picture rlightner  ·  7评论