Mustache.js: Les délimiteurs personnalisés sur Moustache.parse() ne fonctionnent pas depuis 2.3.1

Créé le 9 août 2018  ·  16Commentaires  ·  Source: janl/mustache.js

Depuis la version 2.3.1 , les délimiteurs personnalisés ne fonctionnent apparemment plus pour Mustache.parse() . Voir les exemples suivants :

Ceci est très probablement lié à # 663 et à son correctif. Notez que je peux restaurer cela en utilisant le nouveau Mustache.tags = [...] la place : https://codepen.io/mbrodala/pen/QBJoOx

Pouvez-vous s'il vous plaît jeter un oeil à cela?

Tous les 16 commentaires

Merci beaucoup pour le rapport @mbrodala , ces codepens sont très appréciés !

@mbrodala Merci pour les codepens.
Je me demande s'il y a eu un malentendu ici.

643 et #664 corrigent un bug que j'ai signalé dans #617 , qui est illustré par ce test, qui accompagne #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);
     });
   });

La fonction parse était mise en cache en utilisant uniquement template comme clé de cache, de sorte que la prochaine fois parse est utilisé pour analyser ce modèle, il renverrait exactement les mêmes jetons, même si les tags spécifiés sont différents.

tags est un paramètre facultatif, et lorsqu'il est omis, il revient à mustache.tags , qui est par défaut ['{{', '}}'] . La clé de secours mustache.tags fait partie de la clé de cache.

Je pense que je sais ce qui se passe en ce qui concerne la correction du bogue et les attentes, et je vais essayer de le parcourir, et j'utiliserai le codepen comme exemple.

v2.3.0

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

Dans la version 2.3.0, cela demande à Moustache d'analyser template , en utilisant ['[[', ']]'] comme balises. Moustache le fait et renvoie le résultat correct, mais met en cache l'appel en utilisant uniquement template . Voir lignes 447-450 de [email protected] :

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

Le prochain appel dans le codepen est :

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

render ne prend pas de paramètre tags , donc n'en passe pas un à parse , donc quand render est appelé, parse utilise $#$20$# mustache.tags comme balises. Ainsi, lorsque cet appel render est effectué, il s'agit en fait d'un message parse : "Veuillez analyser template et utiliser implicitement ['{{', '}}'] comme tags ." parse fait en fait la mauvaise chose et effectue une recherche dans le cache en ignorant complètement à la fois tags et mustache.tags . Il arrive de renvoyer le résultat du modèle analysé avec [['[', ']']] , mais uniquement parce que le premier appel à parse dans tout le programme pour ce template a été fait avec ['[[', ']']] comme tags .

v2.3.1

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

Le résultat de l'analyse est mis en cache en utilisant à la fois template et tags , qui est ['[[', ']]'] comme cacheKey.

Le prochain appel :

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

render appelle parse , en passant template mais en omettant tags . parse a donc tags retomber sur mustache.tags , qui reste la valeur par défaut ['{{', '}}'] . parse effectue une recherche de cache sur la clé de cache de template et ['{{', '}}'] , et subit un échec de cache, comme prévu puisque parse n'a pas encore été appelé avec cette combinaison de template et de balises. Il parse donc template en utilisant ['{{', '}}'] .

Je crois que v2.3.1 présente le comportement correct. Si nous devions modifier légèrement le codepen dans https://codepen.io/mbrodala/pen/QBJoOx et l'exécuter avec la v2.3.0 :

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

La sortie est [[item.title]] [[item.value]] , ce qui n'est pas attendu.

Je peux voir à quel point le comportement dans https://codepen.io/mbrodala/pen/NBEJjX peut être surprenant, puisque les appels Mustache.parse et Mustache.render sont juste à côté l'un de l'autre et on pourrait ne pas réalisez même que Mustache.parse prend même un argument tags . (Pourquoi Mustache.parse prend-il même un argument tags ? Il n'est jamais utilisé nulle part dans mustache.js -- parse est simplement par défaut interne à mustache.tags . ..)

Si le changement de comportement défie vraiment les attentes d'une version de correction de bugs, alors je ne sais pas exactement quoi faire. Une possibilité est de publier une autre version de correction de bogues avec # 664 annulé, ce qui supprime en fait tout comportement de mise en cache (étant donné que dans # 643, toutes les recherches de cache seront manquées). Nous pourrions alors remettre #664 dans la prochaine révision majeure. Une autre possibilité consiste à supprimer toute la mise en cache dans une version de correction de bogues (par opposition à la publication d'un mustache.js avec une mise en cache non fonctionnelle), puis à remettre toute la mise en cache dans la prochaine révision majeure. La première option a probablement moins de risque (moins de changement de code) mais la dernière option est probablement plus "correcte". Les pensées de @phillipj ?

Merci beaucoup pour la recherche détaillée qui prend tout son sens à partir de mon point de vue.

Le changement ne me dérangerait pas du tout, mais étant donné qu'il est impossible de passer tags à Mustache.render() pour garantir un accès au cache et que Mustache.parse() est annoncé pour mettre en cache le template (aucune mention de tags ici) Je me demande si cela devrait vraiment être annulé.

Si nous supposons que l'on appelle Mustache.parse avec un ensemble personnalisé de tags , nous pouvons également supposer que le template utilise ces délimiteurs (BTW, "tags" vs "delimiters" devrait être nettoyé aussi). Ensuite, nous pouvons supposer qu'un appel à Mustache.render devrait fonctionner, peu importe comment et si le template donné est déjà mis en cache et comment il a été compilé si tel est le cas. À l'heure actuelle, cela n'est pas garanti en cas d'utilisation de tags personnalisés.

@mbrodala Oui, cela a du sens, bien que Mustache.parse(template, ['[[', ']]']); suivi de Mustache.parse(template, ['((', '))']); donnant exactement le même résultat serait toujours inattendu.

Voici une solution/compromis d'homme de paille ("homme de paille" parce que je n'aime pas ça mais ça vaut le coup de réfléchir). Nous pourrions avoir un cache parse contre template seul et template avec des balises. Lorsque parse est appelé avec tags spécifié, il effectue une recherche sur template et tags . Lorsque nous appelons render , qui appelle parse sans tags , nous effectuons une recherche sur template seul. Les pensées?

Sonne et est fondamentalement, mais résoudra ce problème tout en gardant le correctif intact. OK depuis mon point de vue.

@mbrodala est le problème principal que vous ne pouvez pas passer tags dans render ? Nous pourrions également simplement ajouter un paramètre tags à render .

@petrkoutnysw Est-ce à peu près le problème que vous rencontrez également ?

C'est au moins une incohérence entre parse() et render() . Nous n'utiliserions même pas parse() si nous pouvions effectivement passer des balises personnalisées à render() . Et maintenant, avec une mise en cache appropriée, cela devient plus évident.

+1 pour l'ajout d'un paramètre de balises à render() afin d'éliminer beaucoup de confusion - nous avons également été gênés par ce changement et l'analyse et le rendu du lien n/b ont toujours semblé un peu plus magiques que nécessaire.

D'accord, que diriez-vous de désactiver la mise en cache dans une version de correction de bogue, pour résoudre le problème immédiat et respecter la gestion sémantique des versions, et de la réintroduire et tags dans la méthode render dans la prochaine version majeure ? (Encore une fois, je ne suis pas un grand fan de la solution de l'homme de paille que j'ai proposée.)

Merci beaucoup pour cette procédure détaillée @raymond-lam !

Je penche pour la version de correction de bogue suggérée, principalement en raison de soucis de semver et de projets où ce changement de comportement est inattendu et peut donc causer des ravages dans des projets à l'état sauvage.

En réintroduisant le comportement de mise en cache dans la prochaine version majeure prévue, nous pouvons inclure des instructions de migration dans les notes de version.

@phillipj J'ai émis la pull request #670 qui annule #643 et #664. Plutôt que de désactiver complètement la mise en cache, dans un souci d'atténuation des risques, le simple fait de revenir au comportement v2.3.0 (dans une version de correction de bogues) semble plus sûr pour les personnes dépendantes de Moustache v2.xx. Je vais émettre une autre demande d'extraction à réintroduire dans une version majeure.

@phillipj #671 réintroduit des correctifs de mise en cache, pour attendre une version majeure.

Création du problème n° 672 pour résoudre l'ajout tags à `render.

Merci beaucoup d'avoir examiné et corrigé ce problème, vous êtes super. 👍

Chapeau à @raymond-lam pour celui-ci ! Merci également à vous, crucial pour nous de savoir quand des changements inattendus se produisent dans la nature.

La v2.3.2 a été publiée 🚀

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

SmasherHell picture SmasherHell  ·  18Commentaires

Immortalin picture Immortalin  ·  12Commentaires

barbalex picture barbalex  ·  5Commentaires

ForbesLindesay picture ForbesLindesay  ·  14Commentaires

kuldeepdhaka picture kuldeepdhaka  ·  9Commentaires