Mustache.js: Los delimitadores personalizados en Mustache.parse() no funcionan desde 2.3.1

Creado en 9 ago. 2018  ·  16Comentarios  ·  Fuente: janl/mustache.js

Desde la versión 2.3.1 , los delimitadores personalizados aparentemente ya no funcionan para Mustache.parse() . Vea los siguientes ejemplos:

Lo más probable es que esté relacionado con el n.º 663 y su corrección. Tenga en cuenta que puedo restaurar esto usando el nuevo Mustache.tags = [...] en su lugar: https://codepen.io/mbrodala/pen/QBJoOx

¿Puedes por favor echar un vistazo a esto?

Todos 16 comentarios

Muchas gracias por el informe @mbrodala , ¡esos codepens son muy apreciados!

@mbrodala Gracias por los codepens.
Me pregunto si ha habido un malentendido aquí.

643 y #664 corrigen un error que informé en #617, que se ilustra en esta prueba, que acompaña a #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 función parse estaba almacenando en caché usando solo template como clave de caché, de modo que la próxima vez que se use parse para analizar esa plantilla, devolvería exactamente los mismos tokens, incluso si los tags especificados son diferentes.

tags es un parámetro opcional, y cuando se omite, vuelve a mustache.tags , que por defecto es ['{{', '}}'] . El respaldo mustache.tags se usa como parte de la clave de caché.

Creo que sé lo que está pasando con respecto a la corrección de errores y las expectativas, e intentaré analizarlo, y usaré el codepen como ejemplo.

v2.3.0

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

En 2.3.0, esto le indica a Mustache que analice template , usando ['[[', ']]'] como etiquetas. Moustache lo hace y devuelve el resultado correcto, pero almacena en caché la llamada usando solo template . Ver líneas 447-450 de [email protected] :

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

La próxima llamada en el codepen es:

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

render no toma un parámetro tags , por lo que no pasa uno a parse , por lo que cuando se llama a render , parse usa mustache.tags como sus etiquetas. Entonces, cuando se realiza esa llamada render , es efectivamente un parse , "Por favor analice template e implícitamente use ['{{', '}}'] como tags ". parse en realidad hace lo incorrecto y realiza una búsqueda en caché ignorando por completo tanto tags como mustache.tags . Sucede que devuelve el resultado de la plantilla analizada con [['[', ']']] , pero solo porque la primera llamada a parse en todo el programa para ese template se realizó con ['[[', ']']] como tags .

v2.3.1

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

El resultado del análisis se almacena en caché usando template y tags , que es ['[[', ']]'] como cacheKey.

La próxima llamada:

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

render llama a parse , pasando template pero omitiendo tags . parse por lo tanto tiene tags recurriendo a mustache.tags , que sigue siendo el valor predeterminado ['{{', '}}'] . parse hace una búsqueda de caché contra la clave de caché de template y ['{{', '}}'] , e incurre en un error de caché, como se esperaba ya que parse aún no se había llamado con esa combinación de template y etiquetas. Por lo tanto, analiza template usando ['{{', '}}'] .

Creo que v2.3.1 exhibe el comportamiento correcto. Si tuviéramos que cambiar ligeramente el codepen en https://codepen.io/mbrodala/pen/QBJoOx y ejecutarlo contra v2.3.0:

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

El resultado es [[item.title]] [[item.value]] , que no se esperaba.

Puedo ver cómo el comportamiento en https://codepen.io/mbrodala/pen/NBEJjX puede ser sorprendente, ya que las llamadas Mustache.parse y Mustache.render están una al lado de la otra y es posible que una no incluso darse cuenta de que Mustache.parse incluso toma un argumento tags . (¿Por qué Mustache.parse incluso toma un argumento tags ? Nunca se usa en ningún lugar en mustache.js -- parse simplemente tiene un valor predeterminado interno de mustache.tags . ..)

Si el cambio en el comportamiento realmente desafía las expectativas de un lanzamiento de corrección de errores, entonces no estoy exactamente seguro de qué hacer. Una posibilidad es lanzar otra versión de corrección de errores con el # 664 revertido, lo que en efecto elimina todo el comportamiento de almacenamiento en caché (dado que en el # 643, todas las búsquedas de caché se perderán). Entonces podríamos volver a colocar el #664 en la próxima revisión importante. Otra posibilidad es eliminar todo el almacenamiento en caché en una versión de corrección de errores (en lugar de lanzar un mustache.js con almacenamiento en caché no funcional) y luego volver a colocar todo el almacenamiento en caché en la próxima revisión principal. La primera opción probablemente tiene menos riesgo (menor cantidad de cambio de código), pero la última opción es probablemente más "correcta". ¿Pensamientos de @phillipj ?

Muchas gracias por la investigación detallada que tiene mucho sentido desde mi punto de vista.

No me importaría el cambio en absoluto, pero dado que es imposible pasar tags a Mustache.render() para garantizar un acierto de caché y que Mustache.parse() se anuncia para almacenar en caché el template (sin mención de tags aquí) Me pregunto si esto realmente debería revertirse.

Si asumimos que uno llama a Mustache.parse con un conjunto personalizado de tags , también podemos suponer que template usa estos delimitadores (por cierto, "etiquetas" frente a "delimitadores" deben ser aclarado también). Después de eso, podemos suponer que se espera que funcione una llamada a Mustache.render , sin importar cómo y si el template dado ya está en caché y cómo se compiló, si ese es el caso. En este momento, esto no está garantizado en caso de que se usen tags personalizados.

@mbrodala Sí, eso tiene sentido, aunque Mustache.parse(template, ['[[', ']]']); seguido de Mustache.parse(template, ['((', '))']); dando exactamente el mismo resultado aún sería inesperado.

Aquí hay una solución / compromiso de hombre de paja ("hombre de paja" porque no me gusta, pero vale la pena hacer una lluvia de ideas). Podríamos tener parse caché contra template solo y template con etiquetas. Cuando se llama a $ parse con tags especificado, realiza una búsqueda en template y tags . Cuando llamamos a render , que llama a parse sin tags , hacemos una búsqueda contra template solo. ¿Pensamientos?

Suena mal y básicamente lo es, pero solucionará este problema manteniendo la solución intacta. OK desde mi punto de vista.

@mbrodala es el problema central que no puede pasar tags a render ? También podríamos agregar un parámetro tags a render .

@petrkoutnysw ¿Es este más o menos el problema que ha estado experimentando también?

Es al menos una inconsistencia entre parse() y render() . Ni siquiera usaríamos parse() si pudiéramos pasar etiquetas personalizadas a render() . Y ahora, con el almacenamiento en caché adecuado, esto se vuelve más obvio.

+1 por agregar un parámetro de etiquetas a render() para eliminar mucha confusión; también nos mordió este cambio y el análisis y renderizado en blanco y negro del enlace siempre parecía un poco más mágico de lo necesario.

Bien, entonces, ¿qué tal si deshabilitamos el almacenamiento en caché en una versión de corrección de errores, para solucionar el problema inmediato y cumplir con el control de versiones semántico, y lo volvemos a introducir junto con tags en el método render en la próxima versión principal? (Nuevamente, no soy un gran admirador de la solución de hombre de paja que propuse).

¡Muchas gracias por ese tutorial completo @raymond-lam!

Me inclino por la versión de corrección de errores sugerida, principalmente debido a preocupaciones y proyectos de Semver en los que este cambio de comportamiento es inesperado y, por lo tanto, puede causar estragos en proyectos en la naturaleza.

Al volver a introducir el comportamiento de almacenamiento en caché nuevamente en la próxima versión importante planificada, podemos incluir instrucciones de migración en las notas de la versión.

@phillipj Emití la solicitud de extracción n.º 670 que revierte los números 643 y 664. En lugar de deshabilitar el almacenamiento en caché por completo, en aras de la mitigación de riesgos, simplemente volver al comportamiento v2.3.0 (en una versión de corrección de errores) parece más seguro para los dependientes de Moustache v2.xx. Emitiré otra solicitud de extracción para reintroducirla en una versión principal.

@phillipj #671 reintroduce correcciones de almacenamiento en caché, para esperar una versión principal.

Se creó el problema #672 para abordar la adición tags a `render.

Muchas gracias por investigar y arreglar esto, chicos geniales. 👍

¡Felicitaciones a @raymond-lam por este! Gracias a ti también, crucial para que sepamos cuándo ocurren cambios inesperados en la naturaleza.

v2.3.2 ha sido publicado 🚀

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

funston picture funston  ·  7Comentarios

connor11528 picture connor11528  ·  3Comentarios

kuldeepdhaka picture kuldeepdhaka  ·  9Comentarios

Immortalin picture Immortalin  ·  12Comentarios

chlab picture chlab  ·  11Comentarios