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?
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.
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.
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
.
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 🚀