Mustache.js: Delimitadores personalizados em Mustache.parse() não funcionam desde 2.3.1

Criado em 9 ago. 2018  ·  16Comentários  ·  Fonte: janl/mustache.js

Desde a versão 2.3.1, os delimitadores personalizados aparentemente não funcionam mais para Mustache.parse() . Veja os seguintes exemplos:

Isso provavelmente está relacionado ao #663 e sua correção. Observe que posso restaurar isso usando o Mustache.tags = [...] mais recente: https://codepen.io/mbrodala/pen/QBJoOx

Por favor, você pode dar uma olhada nisso?

Todos 16 comentários

Muito obrigado pelo relato @mbrodala , esses codepens são muito apreciados!

@mbrodala Obrigado pelos codepens.
Eu me pergunto se houve um mal-entendido aqui.

643 e #664 corrigem um bug que relatei em #617 , que é ilustrado por este teste, que acompanha o #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);
     });
   });

A função parse estava armazenando em cache usando apenas template como chave de cache, de modo que da próxima vez que parse fosse usado para analisar esse modelo, ele retornaria exatamente os mesmos tokens, mesmo se os tags especificados forem diferentes.

tags é um parâmetro opcional e, quando omitido, volta para mustache.tags , que por padrão é ['{{', '}}'] . O fallback mustache.tags é usado como parte da chave de cache.

Acho que sei o que está acontecendo com relação à correção do bug e às expectativas, e tentarei orientá-lo e usarei o codepen como exemplo.

v2.3.0

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

Na versão 2.3.0, isso instrui o Mustache a analisar template , usando ['[[', ']]'] como tags. Mustache faz isso e retorna o resultado correto, mas armazena em cache a chamada usando apenas template . Veja as linhas 447-450 de [email protected] :

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

A próxima chamada no codepen é:

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

render não recebe um parâmetro tags , então não passa um para parse , então quando render é chamado, parse usa mustache.tags como suas tags. Então, quando essa chamada render é feita, é efetivamente um parse , "Por favor, analise template e implicitamente use ['{{', '}}'] como tags ." parse realmente faz a coisa errada e faz uma pesquisa de cache ignorando completamente tags e mustache.tags . Acontece de retornar o resultado do template analisado com [['[', ']']] , mas apenas porque a primeira chamada para parse em todo o programa para aquele template foi feita com ['[[', ']']] como tags .

v2.3.1

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

O resultado da análise é armazenado em cache usando template e tags , que é ['[[', ']]'] como cacheKey.

A próxima chamada:

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

render chama parse , passando template mas omitindo tags . parse , portanto, tem tags de volta para mustache.tags , que continua sendo o padrão ['{{', '}}'] . parse faz uma pesquisa de cache na chave de cache de template e ['{{', '}}'] , e incorre em uma falha de cache, como esperado, pois parse ainda não foi chamado com essa combinação de template e tags. Portanto, ele analisa template usando ['{{', '}}'] .

Eu acredito que v2.3.1 exibe o comportamento correto. Se tivéssemos que alterar o codepen em https://codepen.io/mbrodala/pen/QBJoOx ligeiramente e executá-lo na v2.3.0:

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

A saída é [[item.title]] [[item.value]] , o que não é esperado.

Eu posso ver como o comportamento em https://codepen.io/mbrodala/pen/NBEJjX pode ser surpreendente, já que as chamadas Mustache.parse e Mustache.render estão uma ao lado da outra e uma pode não até perceber que Mustache.parse até leva um argumento tags . (Por que Mustache.parse aceita um argumento tags ? Nunca é usado em nenhum lugar em mustache.js -- parse simplesmente padroniza internamente para mustache.tags . ..)

Se a mudança de comportamento realmente desafia as expectativas de um lançamento de correção de bugs, então não sei exatamente o que fazer. Uma possibilidade é lançar outra versão de correção de bug com o #664 revertido, o que na verdade remove todo o comportamento de cache (dado que no #643, todas as pesquisas de cache serão perdidas). Poderíamos então colocar o #664 de volta na próxima grande revisão. Outra possibilidade é remover todo o cache em uma versão de correção de bug (em vez de liberar um mustache.js com cache não funcional) e, em seguida, colocar todo o cache de volta na próxima revisão principal. A primeira opção provavelmente tem menos risco (menor quantidade de mudança de código), mas a última opção é provavelmente mais "correta". @phillipj pensamentos?

Muito obrigado pela pesquisa detalhada que faz todo o sentido do meu ponto de vista.

Eu não me importaria com a mudança, mas dado que é impossível passar tags para Mustache.render() para garantir um acerto de cache e que Mustache.parse() é anunciado para armazenar em cache o template (sem menção de tags aqui) Gostaria de saber se isso realmente deveria ser revertido.

Se assumirmos que alguém chama Mustache.parse com um conjunto personalizado de tags , também podemos assumir que template usa esses delimitadores (BTW, "tags" vs "delimiters" devem ser clareou também). Em seguida, podemos supor que uma chamada para Mustache.render deve funcionar, não importa como e se o template dado já está armazenado em cache e como foi compilado, se for o caso. No momento, isso não é garantido caso tags personalizados sejam usados.

@mbrodala Sim, isso faz sentido, embora Mustache.parse(template, ['[[', ']]']); seguido por Mustache.parse(template, ['((', '))']); dando exatamente o mesmo resultado ainda seria inesperado.

Aqui está uma solução/compromisso de homem de palha ("homem de palha" porque eu não gosto, mas vale a pena fazer um brainstorming). Poderíamos ter parse cache contra template sozinho e template com tags. Quando parse é chamado com tags especificado, ele faz uma pesquisa contra template e tags . Quando chamamos render , que chama parse sem tags , fazemos uma pesquisa apenas contra template . Pensamentos?

Parece estranho e basicamente é, mas corrigirá esse problema, mantendo a correção intacta. OK do meu ponto de vista.

@mbrodala é a questão central que você não pode passar tags para render ? Também poderíamos adicionar um parâmetro tags a render .

@petrkoutnysw Esse é aproximadamente o problema que você também está enfrentando?

É pelo menos uma inconsistência entre parse() e render() . Nós nem usaríamos parse() se pudéssemos passar tags personalizadas para render() . E agora, com o cache adequado, isso se torna mais óbvio.

+1 para adicionar um parâmetro de tags a render() para eliminar muita confusão - também fomos afetados por essa mudança e o link b/w parse e render sempre pareceu um pouco mais mágico do que o necessário.

Ok, então que tal desabilitarmos o cache em uma versão de correção de bug, para corrigir o problema imediato e cumprir o versionamento semântico, e reintroduzi-lo e tags no método render na próxima versão principal? (Mais uma vez, não sou um grande fã da solução do espantalho que propus.)

Muito obrigado por esse passo a passo completo @raymond-lam!

Estou inclinado para o lançamento de correção de bug sugerido, principalmente por causa de preocupações e projetos em que essa mudança de comportamento é inesperada e, portanto, pode causar estragos em projetos em estado selvagem.

Reintroduzindo o comportamento de armazenamento em cache novamente na próxima versão principal planejada, podemos incluir instruções de migração nas notas da versão.

@phillipj Emiti o pull request #670 que reverte #643 e #664. Em vez de desabilitar o cache todos juntos, por uma questão de mitigação de risco, simplesmente voltar ao comportamento v2.3.0 (em uma versão de correção de bugs) parece mais seguro para dependentes do Mustache v2.xx Vou emitir outra solicitação de pull para reintroduzir em uma versão principal.

@phillipj #671 reintroduz correções de cache, para aguardar um grande lançamento.

Criou o problema #672 para abordar a adição de tags ao `render.

Muito obrigado por investigar e consertar isso, vocês são demais. 👍

Tiramos o chapéu para @raymond-lam por este! Graças a você também, é crucial para nós sabermos quando mudanças inesperadas acontecem na natureza.

v2.3.2 foi publicado 🚀

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

ForbesLindesay picture ForbesLindesay  ·  14Comentários

rlightner picture rlightner  ·  7Comentários

connor11528 picture connor11528  ·  3Comentários

MatthijsZw picture MatthijsZw  ·  18Comentários

funston picture funston  ·  7Comentários