Авторский проект IT-специалиста Олега Барабанова Персональные публикации на тему IT и не только…

EJS — что это за шаблонизатор и в каких случаях он может быть полезен в современной web-разработке

Любопытно, что в мире современной web-разработке все ещё находится место использованию таких старых и проверенных инструментов, как EJS, вместо повсеместного (и не всегда уместного) использования современных компонентных фреймворков, наподобие Vue/React/Angular.

EJS (Embedded JavaScript templates) представляет собой простой JS-шаблонизатор, который был когда-то очень популярным в среде матерых фронтендеров, да и сейчас вполне находит применение. Я уж думаю не надо объяснять, зачем вообще в разработке нужны шаблонизаторы.

 

 

На мой взгляд у EJS можно выделить несколько плюсов, по сравнению с многими другими JS-шаблонизаторами:

В общем это чистый JS -шаблонизатор, который заточен именно под шаблонизацию и ничего более.

Несколько примеров синтаксиса EJS

Сам по себе синтаксис представляет собой теги вида <% %> (их есть несколько видов), внутри которых пишется простейший JavaScript. Например так (пример из документации):

<% if (user) { %>
  <h2><%= user.name %></h2>
<% } %>

Тег вида <%= user.name %> просто выводит значение user.name с экранированием символов. Если нужно вывести без экранирования (часто не рекомендуется), то тогда используется тег вида <%- %>

В тегах <% %> вы вполне можете написать любой удобный вам JS-код, для последующей более удобной его обработки в шаблонах. Например что-то вроде этого:

<%
const filteredData = […].map((elem) => …).filter((elem) => …).reverse();
%>

<ul>
<% for (let item of filteredData) { %>
  <li><%= item %></li>
<% } %>
</ul>

Для использования других шаблонов (скорее подшаблонов) в коде, в EJS есть специальная функция include() :

<body>
  <%- include('src/header.ejs', {title: 'Hello World'}) %>
  <%- include('src/main.ejs') %>
  <%- include('src/footer.ejs') %>
</body>

В примере выше можно заметить, что в include() помимо пути к шаблону, можно передавать дополнительные данные этому шаблону для обработки и отображения.

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

Почему я иногда для верстки использую именно EJS

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

Как я уже не раз упоминал, я предпочитаю подбирать инструменты в зависимости от решаемой задачи и того, как это будет дальше будет поддерживаться. Когда я делаю веб-приложение, я беру тот же Vue (+ кучу еще всяких расширений к нему) и клепаю нужные компоненты. Но вот если мне нужно сделать простую верстку которую я затем буду передавать другому специалисту, то тут надо обходиться по возможности максимально простыми и доступными всем решениями. На то есть несколько причин:

  1. Человек который будет принимать верстку, не обязательно будет знать Vue. Если это backend-разработчик на каком-нибудь PHP или Python, то им зачастую нужны простые и ясные HTML-шаблоны. Ведь если такому разработчику который отвечает за бэкэнд, одни верстальщики будут высылать верстку в виде Vue-компонентов, другие в виде React-компонентов, а третьи вообще в виде Angular-компонентов, просто потому что им так удобно, то так можно и с ума сойти. А потом опять будем удивляться, почему некоторые бэкэндеры с ужасом смотрят на безумие фреймворков на фронтенде.
  2. Не все верстальщики знают именно Vue (React / Angular и т.д.). Т.е. для того, чтобы доработать вашу верстку или внести правки, верстальщику, который имел опыт только с React, волей-неволей придется будет копаться во Vue. Тут вообще надо учитывать тот факт, что жизненный цикл верстки не заканчивается на моменте ее передачи, ибо еще в течение некоторого времени скорее всего найдутся какие-либо баги которые нужно будет править, ну или в процессе появятся какие-либо доработки. И какое-то время это надо будет делать именно в исходнике верстки.
  3. Vue/React/Angular работают с виртуальным DOM и соответственно при наличии внешних сторонних скриптов, это может привести к конфликтам или усложнению кода. Для тех кто с этими фреймворками работает, в этом нет ничего особенного, ибо это рядовой случай, но для тех, кому нужна просто верстка, это становится излишним переусложнением.

Т.е. с вашей версткой в итоге могут работать как бэкендеры, так и другие фронтенд-разработчики, которые не факт что знакомы именно с вашим специфичным стеком технологий. И тогда лучше все-таки ограничиваться (в разумных пределах) теми технологиями, которые известны большинству в команде. В нашем случае, это все тот-же стек из HTML/JS/CSS. И соответственно тут как раз и становится удобен EJS, ибо у него синтаксис как раз представляет собой простейший JavaScript.

А вообще, EJS не только для верстки удобен, он также вполне неплох и при использовании в качестве шаблонизатора для фреймворка ExpressJS.

Маленький нюанс, который иногда меня раздражает в синтаксисе EJS

К сожалению при всех плюсах этого шаблонизатора, я не могу не упомянуть один навязчивый момент, который местами меня раздражает. А заключается он именно в некоторой неудобности фигурных скобок { }, особенно когда их много:

<% if (!isHidden) { %>
<div>
  <% for (let item of data) { %>
  <div>
    <% if (item === '...') { %>
    <div>...</div>
    <% } else { %>
    <div>...</div>
    <% } %>
  </div>
  <% } %>
</div>
<% } %>

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

<?php if (!$isHidden): ?>
<div>
  <?php foreach ($item of $data): ?>
  <div>
    <?php if (item === '...'): ?>
    <div><?= item ?></div>
    <?php else: ?>
    <div>...</div>
    <?php endif; ?>
  </div>
  <?php endforeach; ?>
</div>
<?php endif; ?>

Тут конечно достаточно многословно, но эти endif; endfor; endforeach; вместо кучи безликих закрывающих скобок, местами облегчают чтение кода, особенно если шаблон немаленький и довольно-таки сложный.

Но это я просто поделился с вами своими мыслями, ибо все это вкусовщина и кому-то вариант с фигурными скобками может казаться существенно удобней. Да и в общем-то это является чужеродным синтаксисом для JS, что в чем-то нарушает саму идею шаблонизатора EJS в плане использования нативного синтаксиса JS.

Заключение

Резюмируя, я хочу сказать, что компонентные реактивные фреймворки, аля Vue/React/Angular - это безусловно отличные инструменты, дающие широчайшие возможности и которые я сам активно использую. Но все-таки в некоторых задачах их использование является местами чрезмерным.

В свою очередь EJS является старым и проверенным шаблонизатором, который достаточно прост и базируется на многим знакомом синтаксисе JavaScript. Т.е. если разработчик знает базовый JavaScript, то фактически он уже умеет пользоваться и EJS, что местами может оказаться немаловажным фактором в выборе именно этого инструмента.