Mustache.js: Benutzerdefinierte Trennzeichen für Moustache.parse() funktionieren seit 2.3.1 nicht mehr

Erstellt am 9. Aug. 2018  ·  16Kommentare  ·  Quelle: janl/mustache.js

Seit Version 2.3.1 funktionieren benutzerdefinierte Trennzeichen anscheinend nicht mehr für Mustache.parse() . Siehe die folgenden Beispiele:

Dies hängt höchstwahrscheinlich mit # 663 und seiner Lösung zusammen. Beachten Sie, dass ich dies wiederherstellen kann, indem ich stattdessen das neuere Mustache.tags = [...] verwende: https://codepen.io/mbrodala/pen/QBJoOx

Kannst du dir das bitte ansehen?

Alle 16 Kommentare

Vielen Dank für den Bericht @mbrodala , diese Codepens werden sehr geschätzt!

@mbrodala Danke für die Codestifte.
Ich frage mich, ob hier ein Missverständnis vorliegt.

643 und #664 beheben einen Fehler, den ich in #617 gemeldet habe, was durch diesen Test veranschaulicht wird, der #643 begleitet:

  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);
     });
   });

Die parse -Funktion hat beim Caching nur template als Cache-Schlüssel verwendet, sodass beim nächsten Mal, wenn parse zum Analysieren dieser Vorlage verwendet wird, sogar genau dieselben Token zurückgegeben werden wenn die angegebenen tags unterschiedlich sind.

tags ist ein optionaler Parameter, und wenn er weggelassen wird, fällt er auf mustache.tags zurück, was standardmäßig ['{{', '}}'] ist. Der Fallback mustache.tags wird als Teil des Cache-Schlüssels verwendet.

Ich denke, ich weiß, was in Bezug auf die Fehlerbehebung und die Erwartungen vor sich geht, und ich werde versuchen, es durchzugehen, und ich werde den Codepen als Beispiel verwenden.

v2.3.0

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

In 2.3.0 weist dies Moustache an, template zu parsen, wobei ['[[', ']]'] als Tags verwendet werden. Moustache tut dies und gibt das richtige Ergebnis zurück, speichert den Aufruf jedoch nur mit template . Siehe Zeilen 447-450 von [email protected] :

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

Der nächste Aufruf im Codepen lautet:

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

render akzeptiert keinen tags Parameter, übergibt also keinen an parse , wenn also render aufgerufen wird, verwendet parse mustache.tags als Tags. Wenn also dieser render -Aufruf getätigt wird, ist es im Grunde ein sagender parse : „Bitte analysieren Sie template und verwenden Sie ['{{', '}}'] implizit als tags ." parse macht tatsächlich das Falsche und führt eine Cache-Suche durch, wobei sowohl tags als auch mustache.tags vollständig ignoriert werden. Es passiert, dass das Ergebnis der mit [['[', ']']] geparsten Vorlage zurückgegeben wird, aber nur, weil der erste Aufruf von parse im gesamten Programm für dieses template mit ['[[', ']']] gemacht wurde tags .

v2.3.1

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

Das Parsing-Ergebnis wird mit template und tags , was ['[[', ']]'] als CacheKey entspricht.

Der nächste Anruf:

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

render ruft parse und übergibt template , lässt aber tags aus. parse hat daher tags Fallback auf mustache.tags , was der Standard ['{{', '}}'] bleibt. parse führt eine Cache-Suche mit den Cache-Schlüsseln von template und ['{{', '}}'] durch und verursacht einen Cache-Miss, wie erwartet, da parse noch nicht aufgerufen wurde mit dieser Kombination aus template und Tags. Es parst daher template mit ['{{', '}}'] .

Ich glaube, v2.3.1 zeigt das richtige Verhalten. Wenn wir den Codepen in https://codepen.io/mbrodala/pen/QBJoOx leicht ändern und gegen v2.3.0 laufen lassen:

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

Die Ausgabe ist [[item.title]] [[item.value]] , was nicht erwartet wird.

Ich kann sehen, wie das Verhalten in https://codepen.io/mbrodala/pen/NBEJjX überraschend sein könnte, da die Aufrufe Mustache.parse und Mustache.render direkt nebeneinander stehen und einer möglicherweise nicht sogar erkennen, dass Mustache.parse sogar ein tags Argument akzeptiert. (Warum nimmt Mustache.parse überhaupt ein Argument tags ? Es wird nirgendwo in mustache.js verwendet – parse wird intern einfach auf mustache.tags . ..)

Wenn die Verhaltensänderung wirklich den Erwartungen eines Bugfix-Releases widerspricht, dann bin ich mir nicht ganz sicher, was ich tun soll. Eine Möglichkeit besteht darin, eine weitere Bugfix-Version mit zurückgesetztem #664 zu veröffentlichen, wodurch das gesamte Caching-Verhalten entfernt wird (vorausgesetzt, dass in #643 alle Cache-Lookups verfehlt werden). Wir könnten dann #664 wieder in die nächste große Überarbeitung stecken. Eine andere Möglichkeit besteht darin, das gesamte Caching in einem Bugfix-Release zu entfernen (im Gegensatz zur Veröffentlichung eines mustache.js mit nicht funktionierendem Caching) und dann das gesamte Caching in die nächste größere Revision zurückzusetzen. Die erstere Option birgt wahrscheinlich ein geringeres Risiko (geringste Codeänderung), aber die letztere Option ist wahrscheinlich "richtiger". @phillipj Gedanken?

Vielen Dank für die detaillierte Recherche, die aus meiner Sicht voll und ganz Sinn macht.

Ich hätte nichts gegen die Änderung, aber da es unmöglich ist, tags an Mustache.render() zu übergeben, um einen Cache-Treffer sicherzustellen, und dass Mustache.parse() angekündigt wird, um das template zu cachen tags hier) Ich frage mich, ob dies wirklich rückgängig gemacht werden sollte.

Wenn wir davon ausgehen, dass man Mustache.parse mit einem benutzerdefinierten Satz von tags aufruft, können wir auch davon ausgehen, dass template diese Trennzeichen verwendet (übrigens, „tags“ vs. „delimiters“ sollten sein auch aufgeräumt). Danach können wir davon ausgehen, dass ein Aufruf von Mustache.render funktionieren soll, egal wie und ob das angegebene template bereits zwischengespeichert ist und wie es kompiliert wurde, falls dies der Fall ist. Im Moment ist dies nicht garantiert, falls benutzerdefinierte tags verwendet werden.

@mbrodala Ja, das macht Sinn, obwohl Mustache.parse(template, ['[[', ']]']); gefolgt von Mustache.parse(template, ['((', '))']); , das genau das gleiche Ergebnis liefert, immer noch unerwartet wäre.

Hier ist eine Strohmann-Lösung/Kompromiss ("Strohmann", weil ich es nicht mag, aber es ist ein Brainstorming wert). Wir könnten parse sowohl gegen template alleine als auch gegen template mit Tags cachen. Wenn parse mit der Angabe von tags aufgerufen wird, führt es eine Suche nach template und tags durch. Wenn wir render anrufen, was parse ohne tags aufruft, führen wir eine Suche nur gegen template durch. Gedanken?

Klingt aus und ist es im Grunde auch, aber es wird dieses Problem beheben, während das Update intakt bleibt. OK aus meiner Sicht.

@mbrodala ist das Kernproblem, dass Sie tags nicht an render übergeben können? Wir könnten auch einfach einen tags Parameter zu render hinzufügen.

@petrkoutnysw Ist das ungefähr das Problem, das Sie auch erlebt haben?

Es ist zumindest eine Inkonsistenz zwischen parse() und render() . Wir würden nicht einmal parse() verwenden, wenn wir tatsächlich benutzerdefinierte Tags an render() übergeben könnten. Und jetzt mit dem richtigen Caching wird dies offensichtlicher.

+1 für das Hinzufügen eines Tags-Parameters zu render(), um viel Verwirrung zu beseitigen - wir wurden auch von dieser Änderung etwas mitgenommen, und die Verknüpfung s/w parse und render schien immer ein bisschen magischer als nötig zu sein.

Okay, wie wäre es also, wenn wir das Caching in einer Bugfix-Version deaktivieren, um das unmittelbare Problem zu beheben und die semantische Versionierung einzuhalten, und es und tags in der Methode render in der nächsten Hauptversion wieder einführen? (Auch hier bin ich kein großer Fan der von mir vorgeschlagenen Strohmannlösung.)

Vielen Dank für diese gründliche Komplettlösung @raymond-lam!

Ich neige zur vorgeschlagenen Fehlerbehebungsversion, hauptsächlich aufgrund einiger Bedenken und Projekte, bei denen diese Verhaltensänderung unerwartet ist und daher in Projekten in freier Wildbahn Chaos anrichten kann.

Durch die erneute Einführung des Caching-Verhaltens in der geplanten nächsten Hauptversion können wir Migrationsanweisungen in die Versionshinweise aufnehmen.

@phillipj Ich habe die Pull-Anforderung Nr. 670 ausgegeben, die Nr. 643 und Nr. 664 zurücksetzt. Anstatt das Caching insgesamt aus Gründen der Risikominderung zu deaktivieren, scheint es für Abhängige von Moustache v2.xx am sichersten, einfach zum v2.3.0-Verhalten (in einer Bugfix-Version) zurückzukehren. Ich werde einen weiteren Pull-Request zur Wiedereinführung in einer Hauptversion senden.

@phillipj #671 führt Caching-Korrekturen wieder ein, um auf eine Hauptversion zu warten.

Issue #672 erstellt, um das Hinzufügen tags zu `render.

Vielen Dank, dass Sie sich das angesehen und behoben haben, Jungs. 👍

Hut ab vor @raymond-lam dafür! Auch dank Ihnen ist es wichtig, dass wir wissen, wann unerwartete Änderungen in freier Wildbahn auftreten.

v2.3.2 wurde veröffentlicht 🚀

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

barbalex picture barbalex  ·  5Kommentare

rlightner picture rlightner  ·  7Kommentare

connor11528 picture connor11528  ·  3Kommentare

amper5and picture amper5and  ·  5Kommentare

kuldeepdhaka picture kuldeepdhaka  ·  9Kommentare