Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
340 changes: 340 additions & 0 deletions tools/html-preprocessors/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,340 @@
---
title: "Препроцессоры `HTML`"
description: "Разбираемся, зачем нужны препроцессоры `HTML`, какие задачи они решают и чем отличаются друг от друга."
authors:
- drakesbot12
keywords:
- html
- preprocessors
- pug
- nunjucks
- handlebars
- ejs
related:
- tools/nodejs
- tools/gulp
- tools/bundlers
tags:
- article
---

## Что это такое

`HTML` отлично подходит для описания структуры страницы. Но чем больше становится проект, тем чаще хочется переиспользовать повторяющиеся фрагменты разметки, разбивать большие страницы на части и автоматически генерировать однотипный код.

Для решения таких задач существуют **препроцессоры `HTML`**.

Препроцессор берёт специальный шаблон или набор файлов и превращает их в обычный `HTML`, который понимает браузер.

Схема работы выглядит так:

Шаблон → Препроцессор → HTML

Браузер не умеет работать с препроцессорами напрямую. Перед публикацией проекта их результат всегда преобразуется в обычный `HTML`.

## Немного истории

Проблема повторяющейся разметки появилась почти сразу после того, как сайты перестали быть набором из нескольких `HTML`-страниц.

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

```php
<?php include 'header.php'; ?>
```

Это позволяло хранить шапку сайта в одном месте и использовать её на всех страницах.

Позже появились полноценные шаблонизаторы. Они добавили переменные, условия и циклы, благодаря которым `HTML` можно было генерировать автоматически.

Одними из популярных решений стали:
- **Smarty** для PHP;
- **Twig** для PHP;
- **Jinja** для Python;
- **Handlebars** для JavaScript.

Со временем начали появляться и специализированные `HTML`-препроцессоры. Они были ориентированы не только на подстановку данных, но и на более удобное написание разметки.

Например, в 2010 году появился **`Jade`**, который позже переименовали в **`Pug`**. Он предложил компактный синтаксис без угловых скобок и быстро стал популярным среди разработчиков на `Node.js`.

Затем получили распространение генераторы статических сайтов. Они используют шаблонизаторы и препроцессоры для сборки готового `HTML` ещё до публикации сайта.

Сегодня `HTML`-препроцессоры чаще всего встречаются в:
- генераторах статических сайтов;
- системах документации;
- блогах;
- корпоративных сайтах;
- серверных веб-приложениях.

Хоть современные фреймворки часто предлагают собственные способы создания интерфейсов, идея остаётся той же: писать шаблоны удобнее, чем вручную поддерживать большое количество повторяющегося `HTML`-кода.

## Зачем они нужны

Представьте сайт из нескольких десятков страниц. На каждой есть одинаковые шапка, подвал и меню.

Без дополнительных инструментов придётся копировать один и тот же код в каждый файл:

```html
<header>
<nav>
<!-- Навигация -->
</nav>
</header>
```

Если понадобится изменить меню, придётся редактировать все страницы.

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

Кроме переиспользования компонентов они помогают:
- разбивать большие страницы на маленькие части;
- вставлять данные в шаблоны;
- создавать циклы и условия;
- генерировать повторяющуюся разметку;
- собирать статические сайты.

## Чем препроцессоры отличаются от шаблонизаторов

Термины часто используют как синонимы, но между ними есть небольшая разница.

**Шаблонизатор** отвечает за генерацию `HTML` из шаблона и данных.

Например:

```html
<h1>{{ title }}</h1>
```

После обработки шаблон может превратиться в такой `HTML`:

```html
<h1>Главная страница</h1>
```

**Препроцессор `HTML`** — более широкое понятие. Он может включать шаблонизатор, систему сборки, обработку файлов и другие возможности.

На практике эти термины часто пересекаются, поэтому строгого разделения нет.

## Популярные решения

За время существования веба появилось множество `HTML`-препроцессоров и шаблонизаторов. Некоторые из них стали частью отдельных экосистем, а некоторые используются до сих пор в самых разных проектах.

### `Pug`

**`Pug`** (ранее назывался **`Jade`**) — один из самых известных ``HTML``-препроцессоров для `JavaScript`-экосистемы.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTML - кажется, лишние обратные кавычки, посмотри, пожалуйста


Его главная особенность — отказ от привычных `HTML`-тегов в пользу сокращённого синтаксиса на основе отступов.

Вместо такого `HTML`:

```html
<main>
<h1>Привет, мир!</h1>
<p>Это абзац текста.</p>
</main>
```

можно написать:

```pug
main
h1 Привет, мир!
p Это абзац текста.
```

После компиляции получится обычный `HTML`.

**`Pug`** поддерживает:
- переменные;
- условия;
- циклы;
- подключение других файлов;
- шаблоны и наследование шаблонов;
- миксины (`mixins`) — аналог компонентов.

Например, миксин можно использовать для создания переиспользуемого блока:

```pug
mixin button(text)
button.button= text

+button('Отправить')
```

Плюсы **`Pug`**:
- компактный синтаксис;
- меньше повторяющегося кода;
- удобная работа с компонентами.

Минусы:
- требуется изучить новый синтаксис;
- ошибки в отступах могут ломать структуру документа;
- `HTML` становится менее узнаваемым.

Сегодня **`Pug`** чаще встречается в проектах на `Node.js` и в генераторах статических сайтов.

### `Nunjucks`

**`Nunjucks`** — шаблонизатор от Mozilla, вдохновлённый Python-шаблонизатором `Jinja`.

В отличие от **`Pug`** он сохраняет привычный `HTML` и добавляет специальные конструкции для динамического содержимого.

Переменные записываются так:

```html
<h1>{{ title }}</h1>
```

Условия выглядят так:

```html
{% if isLoggedIn %}
<p>Вы вошли в систему</p>
{% endif %}
```

Циклы:

```html
<ul>
{% for user in users %}
<li>{{ user.name }}</li>
{% endfor %}
</ul>
```

Одно из самых сильных мест **`Nunjucks`** — работа с шаблонами.

Можно создать базовый шаблон страницы:

```html
<!DOCTYPE html>
<html lang="ru">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
```

А затем расширять его:

```html
{% extends "layout.njk" %}

{% block title %}
Главная
{% endblock %}
```

Такой подход особенно удобен для блогов, документации и многостраничных сайтов.

**`Nunjucks`** используется во многих статических генераторах сайтов, включая Eleventy.

### `Handlebars`

**`Handlebars`** развивает идеи более раннего шаблонизатора `Mustache`.

Его философия проста: шаблон отвечает только за отображение данных, а логика должна находиться в коде приложения.

Пример шаблона:

```html
<h1>{{title}}</h1>
<p>{{description}}</p>
```

Подстановка данных:

```js
{
title: 'Дока',
description: 'Добрый справочник для веб-разработчиков'
}
```

Результат:

```html
<h1>Дока</h1>
<p>Добрый справочник для веб-разработчиков</p>
```

**`Handlebars`** поддерживает:
- переменные;
- циклы;
- условия;
- пользовательские помощники (`helpers`);
- частичные шаблоны (`partials`).

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

```html
{{> header}}
```

**`Handlebars`** долгое время активно использовался в `JavaScript`-приложениях и до сих пор встречается в различных `CMS` и инструментах сборки.

Его главное преимущество — простота. Даже человек, плохо знакомый с `JavaScript`, быстро поймёт такой шаблон.

### `EJS`

Название **`EJS`** расшифровывается как `Embedded JavaScript`.

Главная идея — возможность писать обычный `JavaScript` прямо внутри `HTML`-шаблона.

Например:

```html
<ul>
<% users.forEach(user => { %>
<li><%= user.name %></li>
<% }) %>
</ul>
```

Условия выглядят так:

```html
<% if (isAdmin) { %>
<p>Панель администратора</p>
<% } %>
```

**`EJS`** практически не вводит собственных конструкций и позволяет использовать уже знакомый `JavaScript`.

Это одновременно плюс и минус.

Плюсы:
- низкий порог входа для `JavaScript`-разработчиков;
- высокая гибкость;
- минимальное количество новых правил.

Минусы:
- шаблоны могут быстро превращаться в смесь `HTML` и логики;
- сложные файлы становятся труднее поддерживать.

**`EJS`** часто используется в приложениях на `Node.js` вместе с `Express`.

## Когда стоит использовать препроцессор

Препроцессор может пригодиться, если:

- в проекте много повторяющейся разметки;
- нужно собирать статический сайт;
- требуется генерировать страницы из данных;
- хочется разделить большие `HTML`-файлы на небольшие части.

Для небольших страниц или простых лендингов дополнительный этап сборки может оказаться лишним.

## Что выбрать?

У каждого решения своя область применения.

- **`Pug`** подойдёт тем, кто хочет максимально сократить объём `HTML`.
- **`Nunjucks`** удобен для документации, блогов и статических сайтов.
- **`Handlebars`** хорошо подходит для простых шаблонов с минимальным количеством логики.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У меня сомнения, что Handlebars и Nunjucks подходят под определение html препроцессоров.

- **`EJS`** понравится разработчикам, которые хотят использовать обычный `JavaScript` внутри шаблонов.

Выбор зависит не столько от возможностей инструмента, сколько от требований проекта и предпочтений команды.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

1 change: 1 addition & 0 deletions tools/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ groups:
- gulp
- preprocessors
- css-in-js
- html-preprocessors

- name: Развёртывание проекта
items:
Expand Down
Loading