В моей команде разработчиков мы активно используем шаблонизатор Handlebars. Первоначально вилка Mustache, Handlebars по сути является просто компилятором, который принимает выражения HTML и Handlebars, компилирует их в Javascript, а затем вставляет полученную строку в соответствующее место на вашей HTML-странице.

Зачем вообще использовать Handlebars, если тогда можно просто написать стандартный HTML? Мне лично нравится работать с механизмом создания шаблонов, потому что он позволяет мне создавать модульный HTML-код, который я могу упростить и повторно использовать. Но что еще более важно, он отделяет логику (JavaScript) от HTML, который может стать трудным для чтения и управления, поэтому, используя не требующий логики шаблонизатор, такой как Handlebars, вы можете сосредоточиться только на HTML.

Задача

Нашей командой разработчиков был предложен интересный сценарий: как можно условно отображать партиал Handlebars на основе среды Node (производство или разработка). Сценарий, в котором это может быть полезно, - это когда частично отображается какое-то отслеживание Google или другая производственная аналитика. Нам не нужно загружать эту функциональность в нашу среду разработки, поэтому может иметь смысл компилировать эти частичные данные только в производственной среде.

Есть разные способы установки переменной среды Node, но обычно это происходит при запуске среды. Например:

"start-dev": "NODE_ENV='development' npm run dev",
"dev": "gulp && nodemon server.js",

Одна из вещей, которые я упоминал ранее о Handlebars, заключается в том, что он лишен логики. Это означает, что в нем нет явных операторов потока управления, таких как for циклы или if условные выражения. Но он позволяет создавать циклы и условные выражения с использованием встроенных помощников. Вот простой пример условного оператора:

Имея это в виду, я начал думать о том, как передать текущую переменную среды Node (в нашем случае «производство» или «разработка») в партиал.

Решение

Одним из основных отличий Handlebars от своего предшественника, Mustache, является то, что он позволяет нам писать собственные вспомогательные методы, которые мы можем использовать с нашими частичными данными.

С помощью специального помощника мы можем добавить любой тип логики Javascript, который нам нравится, но в этом случае все, что я хотел сделать, это вернуть логическое значение, которое сообщает нам, находимся мы в настоящее время в производственной среде или нет. Поскольку мы уже установили NODE_ENV значение ключа при запуске, мы могли бы зарегистрировать эту относительно простую вспомогательную функцию, которая проверяет значение этого значения:

А применение нашего настраиваемого prod хелпера только частично для продакшена выглядело так:

Но когда я тестировал эту функцию, произошла интересная вещь. Условное выражение #if не оценивало возвращаемое значение настраиваемого помощника. Он всегда оценивался как false.

Я предположил, что либо значения из нашей пользовательской вспомогательной функции не возвращаются как логические, либо встроенный помощник #if вообще не оценивает результат prod.

Проверяя первую теорию, я создал вторую вспомогательную функцию для проверки значения typeof и подтвердил, что оно выводится правильно:

В рамках своей второй теории я начал экспериментировать с подвыражениями, цель которых - передавать результаты одной вспомогательной функции другой. Возьмем, к примеру, следующее с использованием двух вспомогательных функций:

В результате получается строка:

Hello, Jami. How are you?

Хорошо, не очень очевидно, насколько это полезно в нашем случае. В документации не говорится об этом явно, но я догадывался, что я мог бы использовать свой собственный помощник prod, переданный как подвыражение с использованием круглой скобки ( ) syntax, которое затем будет оцениваться встроенным помощником #if как логическое значение. Откуда я это узнал? Я правда не знал! Я просто догадывался, что имею дело с двумя вспомогательными функциями, которым необходимо взаимодействовать друг с другом. Итак, я попробовал и обновил свой партиал:

Теперь условное выражение правильно оценивало логическое значение! Итак, когда наша переменная среды Node установлена ​​на «production», наше представление отображается как:

Seen only in production
This is some example text

И когда он установлен на что-то иное, чем «производство», он не отображает партиал, чего мы и пытались достичь.

Заключение

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

Спасибо за прочтение! Следуй за мной в Twitter 👋🏼