Mustache.js: Пользовательские разделители в Mustache.parse() не работают с версии 2.3.1

Созданный на 9 авг. 2018  ·  16Комментарии  ·  Источник: janl/mustache.js

Начиная с версии 2.3.1 пользовательские разделители больше не работают для Mustache.parse() . См. следующие примеры:

Скорее всего, это связано с #663 и его исправлением. Обратите внимание, что я могу восстановить это, используя вместо этого более новый Mustache.tags = [...] : https://codepen.io/mbrodala/pen/QBJoOx

Не могли бы вы взглянуть на это?

Все 16 Комментарий

Большое спасибо за отчет @mbroda , эти коды очень ценны!

@mbroda Спасибо за кодовые ручки.
Интересно, было ли здесь недоразумение.

643 и #664 исправляют ошибку, о которой я сообщал в #617, что иллюстрируется этим тестом, сопровождающим #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);
     });
   });

Функция parse выполняла кеширование, используя только template в качестве ключа кэша, так что в следующий раз, когда parse будет использоваться для разбора этого шаблона, она вернет точно такие же токены, даже если указанные tags отличаются.

tags — необязательный параметр, и когда он опущен, он возвращается к mustache.tags , что по умолчанию равно ['{{', '}}'] . Откат mustache.tags используется как часть ключа кэша.

Я думаю, что знаю, что происходит в отношении исправления ошибок и ожиданий, и я попытаюсь пройти через это, и я буду использовать codepen в качестве примера.

v2.3.0

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

В версии 2.3.0 это указывает Mustache анализировать template , используя ['[[', ']]'] в качестве тегов. Mustache делает это и возвращает правильный результат, но кэширует вызов, используя только template . См. строки 447-450 [email protected] :

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

Следующий вызов в codepen:

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

render не принимает параметр tags , поэтому не передает его в parse , поэтому при вызове render parse использует mustache.tags в качестве его тегов. Таким образом, когда выполняется этот вызов render , он фактически сообщает parse : «Пожалуйста, проанализируйте template и неявно используйте ['{{', '}}'] как tags ». parse на самом деле делает неправильную вещь и выполняет поиск в кеше, полностью игнорируя как tags , так и mustache.tags . Бывает, что возвращается результат анализа шаблона с [['[', ']']] , но только потому, что первый вызов parse во всей программе для этого template был сделан с ['[[', ']']] как tags .

v2.3.1

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

Результат синтаксического анализа кэшируется с использованием template и tags , что равно ['[[', ']]'] в качестве cacheKey.

Следующий звонок:

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

render вызывает parse , передавая template , но пропуская tags . Таким образом, для $ parse значение tags возвращается к mustache.tags , которое остается значением по умолчанию ['{{', '}}'] . parse выполняет поиск в кеше по ключу кеша template и ['{{', '}}'] и вызывает промах кеша, как и ожидалось, поскольку parse еще не был вызван с этой комбинацией template и тегов. Поэтому он анализирует template с помощью ['{{', '}}'] .

Я считаю, что v2.3.1 показывает правильное поведение. Если бы мы немного изменили codepen в https://codepen.io/mbrodala/pen/QBJoOx и запустили его против версии 2.3.0:

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

Вывод [[item.title]] [[item.value]] не ожидается.

Я вижу, как поведение в https://codepen.io/mbroda/pen/NBEJjX может быть удивительным, поскольку вызовы Mustache.parse и Mustache.render находятся рядом друг с другом, и один может не даже понять, что Mustache.parse даже принимает аргумент tags . (Почему Mustache.parse даже принимает аргумент tags ? Он никогда нигде не используется в mustache.js -- parse просто по умолчанию имеет внутреннее значение mustache.tags . ..)

Если изменение в поведении действительно бросает вызов ожиданиям выпуска исправления ошибок, то я не совсем уверен, что делать. Одна из возможностей состоит в том, чтобы выпустить еще одну версию с исправлением ошибок с откатом #664, который, по сути, удаляет все поведение кэширования (учитывая, что в #643 все поиски в кэше будут пропущены). Затем мы могли бы вернуть #664 в следующую основную версию. Другая возможность — удалить все кэширование в выпуске с исправлением ошибок (в отличие от выпуска mustache.js с нефункциональным кэшированием), а затем вернуть все кэширование в следующей основной версии. Первый вариант, вероятно, имеет меньший риск (наименьшее количество изменений кода), но второй вариант, вероятно, более «правильный». мысли @phillipj ?

Большое спасибо за подробное исследование, которое полностью понятно из моего POV.

Я бы вообще не возражал против этого изменения, но учитывая, что невозможно передать tags в Mustache.render() , чтобы гарантировать попадание в кеш, и что Mustache.parse() объявляется для кэширования template (здесь не упоминается tags ) Интересно, действительно ли это следует отменить.

Если мы предположим, что кто-то вызывает Mustache.parse с пользовательским набором tags , мы также можем предположить, что template использует эти разделители (кстати, «теги» и «разделители» должны быть тоже разобрался). После этого мы можем предположить, что вызов Mustache.render должен работать, независимо от того, как и если данный template уже кэширован и как он был скомпилирован, если это так. Сейчас это не гарантируется в случае использования пользовательских tags .

@mbrodala Да, это имеет смысл, хотя Mustache.parse(template, ['[[', ']]']); , за которым следует Mustache.parse(template, ['((', '))']); , дающее точно такой же результат, все равно было бы неожиданным.

Вот соломенное решение/компромисс («соломенное чучело», потому что мне это не нравится, но стоит провести мозговой штурм). Мы могли бы иметь кэш $# parse 2$#$ как для одного template , так и для template с тегами. Когда parse вызывается с указанным tags , выполняется поиск по template и tags . Когда мы вызываем render , который вызывает parse без tags , мы выполняем поиск только по template . Мысли?

Звучит не так, и в основном это так, но мы исправим эту проблему, сохранив при этом исправление. ОК от моего POV.

@mbroda - это основная проблема, из-за которой вы не можете передать tags в render ? Мы также можем просто добавить параметр tags к render .

@petrkoutnysw Это примерно та же проблема, с которой вы столкнулись?

Это как минимум несоответствие между parse() и render() . Мы бы даже не использовали parse() , если бы действительно могли передавать пользовательские теги в render() . И теперь с правильным кэшированием это становится более очевидным.

+1 за добавление параметра tags в render(), чтобы устранить большую путаницу — мы также получили немного от этого изменения, и ссылка на ч/б анализ и рендеринг всегда казалась немного более волшебной, чем необходимо.

Итак, как насчет того, чтобы отключить кэширование в выпуске с исправлением ошибок, чтобы исправить насущную проблему и обеспечить соблюдение семантического управления версиями, а также повторно ввести его и tags в методе render в следующем основном выпуске? (Опять же, я не большой поклонник предложенного мной соломенного решения.)

Большое спасибо за подробное руководство @raymond-lam!

Я склоняюсь к предлагаемому выпуску исправления ошибок, в основном из-за некоторых проблем и проектов, где это изменение поведения является неожиданным и, следовательно, может вызвать хаос в проектах в дикой природе.

Повторно представляя поведение кэширования снова в запланированном следующем основном выпуске, мы можем включить инструкции по миграции в примечания к выпуску.

@phillipj Я отправил запрос на включение # 670, который откатывает # 643 и # 664. Вместо того, чтобы полностью отключать кэширование, ради снижения риска, просто вернуться к поведению версии 2.3.0 (в выпуске с исправлением ошибок) кажется наиболее безопасным для тех, кто зависит от Mustache v2.xx. Я отправлю еще один запрос на включение для повторного введения в основной выпуск.

@phillipj #671 повторно вводит исправления кэширования, чтобы дождаться основного выпуска.

Создана проблема № 672 для решения вопроса о добавлении tags в `render.

Большое спасибо за изучение и исправление этого, вы молодцы. 👍

Снимаю шляпу перед @raymond-lam за это! Спасибо вам, нам очень важно знать, когда в дикой природе происходят неожиданные изменения.

Опубликована версия 2.3.2 🚀

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

chlab picture chlab  ·  11Комментарии

rlightner picture rlightner  ·  7Комментарии

ForbesLindesay picture ForbesLindesay  ·  14Комментарии

kuldeepdhaka picture kuldeepdhaka  ·  9Комментарии

barbalex picture barbalex  ·  5Комментарии