Генераторы статических сайтов с нуля: словарь терминов, история развития и первая сборка
Изучите термины, которые, по мнению документации SSG, должны быть вам известны: как работают лейауты, частичные файлы и фронт-материалы, откуда появились генераторы сайтов и как выбрать подходящий без лишних проблем.
Генераторы статических сайтов обещают простое решение: пишете посты в формате Markdown, храните заголовок и футер в одном месте, и получаете быстрый сайт из обычных файлов. Однако для многих новичков реальность оказывается полна непонятного жаргона, терминала, выводящего трассировку стека, и документации, предполагающей наличие многолетних знаний в данной области. Этот руководство закрывает этот разрыв с нуля. Вы узнаете, какие навыки необходимо иметь перед началом работы, что на самом деле означают все повторяющиеся термины в документации генераторов, как соединяются компоненты типичного проекта Eleventy, откуда взялись эти инструменты и какие более легкие альтернативы существуют, когда популярные решения кажутся слишком сложными.
Прежде чем выбрать генератор: необходимые навыки
Генератор статических сайтов (SSG) представляет собой слой абстракции, расположенный над веб-страницами. Если вы никогда раньше не создавали веб-страницы вручную, этот слой абстракции скрывает именно те аспекты, которые необходимо понимать при возникновении проблем. Для первых нескольких сайтов лучшим способом обучения будет написание HTML и CSS самостоятельно. Вы почувствуете трудности при копировании одинаковой навигации в десять файлов, и именно эти трудности позже заставят вас обратиться к генератору.
Почти каждый генератор подразумевает, что вы владеете HTML и CSS, часто также небольшими знаниями JavaScript, основными концепциями программирования, такими как переменные и циклы, командной строкой, а также Git. Не обязательно сразу овладевать всем этим. Главное — иметь базовое представление о каждом слое, чтобы превратить загадочные ошибки при сборке в решаемые проблемы, а не в загадки.
План обучения с бесплатными ресурсами
Следующие ресурсы наиболее эффективны, если использовать их примерно в этом порядке. Создавайте небольшие временные сайты по мере работы, вместо того чтобы рассматривать этот список как домашнее задание, которое нужно выполнить в первую очередь.
- HTML: Книга «HTML for People» написана для читателей без какого-либо опыта программирования. Если вам нужно более глубокое изучение семантических элементов и вопросов доступности, обратитесь к разделу MDN, посвященному структурированию контента.
- CSS: Раздел MDN, посвященный основам стилизации, охватывает такие концепции, как модель коробки и макетирование. Если вам больше подходят практические упражнения, курс freeCodeCamp по адаптивному дизайну рассматривает HTML, CSS, вопросы доступности и адаптивный (практически, удобный для мобильных устройств) дизайн.
- JavaScript: Раздел MDN, посвященный скриптингу, логично продолжает материалы по HTML и CSS, а учебная программа freeCodeCamp по JavaScript представляет собой интерактивную альтернативу.
Если вы предпочитаете единый ресурс вместо сборника материалов, раздел обучения MDN охватывает HTML, CSS, JavaScript и основы работы браузеров в рамках одной учебной программы. Дополнительными вариантами являются web.dev, The Odin Project и w3schools.
Не забывайте о контексте: личный веб-сайт обычно является хобби. Нестандартные решения и ошибки — часть процесса, а каждый завершённый небольшой сайт добавляет новые навыки, которые можно применить при создании следующего.
Лексика, которую, согласно документации static-site, вы уже должны знать
В документации генераторов часто используется десяток терминов, как будто все учат их с рождения. В этом разделе они определяются простым языком, а каждый из них показан на примере небольшого конкретного файла из проекта Eleventy (11ty).
Маркап, стиль и поведение: HTML, CSS и JavaScript
HTML (HyperText Markup Language) описывает структуру и смысл документа: заголовки, абзацы, ссылки, изображения, списки. Это не язык программирования. Он не может принимать решения или что-либо повторять самостоятельно; он просто указывает, что находится на странице. Самая минимальная полезная страница содержит doctype, блок <head> с набором символов и заголовком, а также блок <body> с содержимым. Обратите внимание, что здесь нет ничего, что контролировало бы цвета или шрифты, поэтому браузер использует свои стандартные стили.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My First Page</title>
</head>
<body>
<h1>Hello, world!</h1>
<p>This page has a <a href="https://brennan.day">link</a> and a list:</p>
<ul>
<li>HTML gives a page its structure.</li>
<li>There's no CSS yet, so this is all default styling.</li>
</ul>
</body>
</html>Copy
Сохранение этого файла как index.html и его открытие в любом браузере позволяет получить рабочую веб-страницу без необходимости сервера. (Текст Copy, находящийся после закрывающего тега, является остатком кнопки копирования и не входит в структуру маркировки.)
CSS (Cascading Style Sheets) определяет способ отображения этой структуры: цвета, расстояния между элементами, типографику и то, как макет адаптируется к разным размерам экранов. Указанные ниже правила задают использование шрифта с засечками, ограничивают ширину текста для обеспечения читаемости строк, центрируют колонку с автоматическими отступами, а также придают странице теплый фон и темные цвета текста. Для заголовка предусмотрено отдельное правило настройки цвета.
body {
font-family: Georgia, serif;
max-width: 35rem;
margin: 2rem auto;
padding: 0 1rem;
background: #fff2ce;
color: #02005d;
}
h1 {
color: rebeccapurple;
}Copy
Размещение этих правил внутри элемента <style> в разделе <head> страницы позволяет изменить её внешний вид без изменения ни одного слова в HTML-коде. Такое разделение содержимого и форматирования является основной концепцией всех генераторов статических сайтов.
JavaScript — это язык программирования, на котором работают браузеры. Он добавляет функциональность: реагирование на клики, изменение контента, загрузка данных. Однако он также является самым простым способом сделать простую страницу тяжелой и медленной, поэтому хорошим стандартом для личного сайта является использование этого языка только там, где он действительно необходим. Приведенный ниже фрагмент находит элемент с идентификатором surprise, отслеживает клики по нему и заменяет текст первого тега <h1> при происшествии клика.
const button = document.querySelector("#surprise");
button.addEventListener("click", () => {
document.querySelector("h1").textContent = "JavaScript did this!";
});Copy
Чтобы это сработало, на странице должен быть соответствующий тег <button id="surprise">. Без него функция querySelector возвращает значение null, а вызов функции addEventListener приводит к ошибке, что является распространенной первой проблемой.
JavaScript используется не только в браузере, но и на стороне генератора. Многие SSG написаны на JavaScript и используют его для выполнения процесса сборки или обработки шаблонов. Eleventy даже позволяет сделать весь шаблон файлом JavaScript: содержимым страницы становится строка, возвращаемая экспортируемой функцией.
// hello.11ty.js
module.exports = function () {
return "<h1>Hello from JavaScript!</h1>";
};Copy
В этом примере используется синтаксис CommonJS module.exports. В новых версиях Eleventy также поддерживается синтаксис ES-модулей (export default), поэтому уточните, какой стиль используется в документации для вашей установленной версии.
Что на самом деле означают «статический», «сборка» и «вывод»
- Статический тип описывает способ доставки контента: сервер передаёт файл точно таким, каким он хранится, вместо того чтобы генерировать новый ответ для каждого посетителя. Статическая страница всё ещё может содержать JavaScript, её можно редактировать и повторно развертывать. Это никак не означает, что такая страница будет скучной или замороженной навсегда.
- Динамический тип означает, что ответ генерируется в момент запроса. Классическая система управления контентом запрашивает данные из базы данных и собирает страницу при каждом посещении. Типичным примером является интернет-магазин, где ассортимент и корзины постоянно меняются.
- Генератор статических сайтов — это программа, которая читает исходные материалы (контент в формате Markdown, шаблоны, настройки, изображения и другие ресурсы) и создаёт готовый набор файлов HTML, CSS, JavaScript и изображений, которые может хостить любой статический сервер.
_site/, public/ или dist/. Их обычно не редактируют вручную, поскольку следующая сборка их перезаписывает.localhost:8000 и часто автоматически пересобирает контент при сохранении файла исходного кода.Файлы конфигурации и данные сайта
- Файл конфигурации содержит настройки для всего сайта, такие как название сайта, базовый URL, меню, каталог вывода или параметры подкаста. Названия и форматы различаются в зависимости от инструмента:
config.yml,hugo.toml,eleventy.config.jsи другие. - YAML — это удобный для человека формат данных, широко используемый в конфигурациях и преамбулах. Он позволяет представлять строки, числа, списки и пары «ключ-значение». Отступы имеют значение, поэтому одна неправильно размещенная пробел может нарушить процесс сборки.
- Пара ключ-значение — это настройка, состоящая из имени и значения, например
title: My post. В YAML группа таких пар называется маппингом. - Параметр или опция — это настройка, которую вы передаете команде или указываете в файле. Флаг
--serve, с которым вы столкнетесь позже, является одним из примеров.
В Eleventy файлы в папке _data становятся глобальными данными, доступными для каждого шаблона. Файл src/_data/site.json хранит информацию, которую видят посетители: название сайта, краткое описание, автора, публичный URL и язык.
{
"name": "My Cool Blog",
"description": "Where I write about whatever interests me.",
"author": "Your Name",
"url": "https://example.com",
"language": "en"
}
Каждый ключ превращается в переменную шаблона. Лейаут, содержащий {{ site.name }}, отображает значение «My Cool Blog», поэтому для смены названия сайта достаточно изменить одну строку здесь, вместо того чтобы искать изменения на каждой странице. Jekyll хранит аналогичную информацию в файле config.yml, а Hugo — в hugo.toml; суть остаётся прежней, меняется только файл. Следует помнить, что JSON требователен к синтаксису: запятая в конце после последнего элемента является синтаксической ошибкой, и это важный момент, который будет рассмотрен позже в этом руководстве.
Лейауты, частичные элементы и шаблонирование
- Шаблон — это повторно используемый файл, который определяет структуру страницы и содержит места замены для тех элементов, которые могут меняться.
- Макет — это шаблон для всей страницы: указание языка, раздел
<head>, заголовок, основная область содержимого и футер. - Частичный элемент — это небольшой повторно используемый фрагмент, такой как панель навигации, футер или блок метаданных поста. Инструкция include предназначена для включения одного фрагмента в другой файл.
- Язык шаблонизации — это синтаксис для отображения переменных, циклирования по данным и принятия решений внутри шаблонов. Распространенными примерами являются Liquid, Nunjucks и Go templates.
- Условие — это правило «да/нет» в шаблоне, например «отобразить изображение главного элемента только тогда, когда пост его указывает».
Основной шаблон ниже, _includes/layouts/base.njk, написан на Nunjucks. Заголовок формируется путем объединения собственного заголовка страницы и общего названия сайта; два тега include вставляют части заголовка и футера, а отрисованный содержимое страницы выводится внутри тега <main>.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ title }} | {{ site.name }}</title>
</head>
<body>
{% include "partials/header.njk" %}
<main>
{{ content | safe }}
</main>
{% include "partials/footer.njk" %}
</body>
</html>
Фильтр | safe имеет важное значение. Nunjucks по умолчанию экранирует вывод, что превратило бы HTML поста в видимые теги. Указание, что content безопасен, сообщает движку, что эта строка является надежным, уже отрисованным HTML. Используйте его только для контента, который находится под вашим контролем.
Сами части представляют собой просто фрагменты HTML, которые могут использовать переменные и включать другие части. Заголовок содержит ссылку на главную страницу с использованием имени сайта и загружает навигацию; навигация — это обычный список ссылок; в футере отображается строка с авторскими правами, взятая из данных сайта.
<!-- partials/header.njk -->
<header>
<a href="/">{{ site.name }}</a>
{% include "partials/nav.njk" %}
</header>
<!-- partials/nav.njk -->
<nav>
<a href="/">Home</a>
<a href="/archive/">Archive</a>
<a href="/about/">About</a>
</nav>
<!-- partials/footer.njk -->
<footer>
<p>© 2026 {{ site.author }}</p>
</footer>
Вот как соединяются эти элементы. Когда пост в своем фронт-материале указывает layout: base.njk, Eleventy отрисовывает пост, затем размещает результат там, где в лейауте находится {{ content | safe }}, причем каждая тег-инструкция include заменяется на соответствующую часть. Изменив навигацию один раз, все страницы сайта автоматически примут эти изменения при следующей сборке. Именно устранение необходимости в ручном копировании и вставке является основной причиной существования SSG. Есть одно небольшое ограничение: год в футере задан жестко, поэтому он не обновится сам по себе, если только вы не замените его на переменную.
Файлы контента, Markdown и фронт-материал
- Файл контента — это исходный файл для страницы или поста. Наиболее распространенным форматом является Markdown, но многие генераторы принимают также HTML, обычный текст и другие форматы.
- Markdown — это легковесный язык разметки, в котором знаки препинания используются для формирования структуры:
#— для заголовков, звездочки — для выделения, тире — для списков. Генератор преобразует его в HTML. - Фронт-материал — это блок метаданных в самом верхнем разделе файла контента, обычно ограниченный двумя строками из трех тире. В нем могут храниться заголовок, дата, теги, имя макета или флаг черновика.
- Метаданные — это описательная информация об элементе контента: заголовок, автор, дата публикации, теги, описание, канонический URL или выбранный макет.
Файл posts/my-first-post.md, приведённый ниже, объединяет всё это. YAML-метаданные задают название, дату, два тега, формат отображения и флаг черновика. Тело файла содержит обычный Markdown вместе с синтаксисом шаблонов в стиле Nunjucks, который выводит название и условно отображает предложение.
---
title: My First Post
date: 2026-09-22
tags:
- posts
- cats
layout: post.njk
draft: false
---
Welcome to my blog! This paragraph is **Markdown**.
This post is called "{{ title }}".
{% if draft %}
This sentence only appears while the post is a draft.
{% endif %}
Eleventy сначала читает вступительные данные перед отображением любого контента. Параметр layout определяет шаблон форматирования, тег posts добавляет файл в коллекцию с именем posts (которую может перебирать страница архива), а параметр date задаёт порядок сортировки контента с учётом даты публикации. Всё, что находится после закрывающих тире, является основным содержимым страницы. Поскольку здесь значение draft равно false, условное предложение не отображается в результате. Следует иметь в виду, что параметр draft не имеет встроенного значения в Eleventy; исключение черновиков из финальной версии сайта — это то, что нужно настроить самостоятельно.
Хостинг, бэкенды и условия развертывания
- Хостинг — это сервис или сервер, который хранит файлы вашего сайта и обеспечивает их доступность в Интернете. Это отдельная задача, отличная от написания самого сайта и управления версиями кода.
Контроль версий на одной странице
- Контроль версий фиксирует изменения в файлах со временем, что позволяет просматривать историю изменений, сравнивать версии, возвращаться к предыдущим состояниям и сотрудничать.
- Git — это одна из программ для контроля версий. Она работает полностью на вашем компьютере и не требует онлайн-сервисов для отслеживания истории изменений.
- Хранилище (repo) — это папка проекта, историю изменений в которой управляет Git.
- Коммит — это сохраненная копия изменений, обычно с сообщением, описывающим их.
- Удаленное хранилище — это еще одна копия хранилища, часто размещаемая на Codeberg, GitHub, GitLab или вашем собственном сервере.
- Push отправляет ваши локальные коммиты на удаленный репозиторий; pull загружает коммиты с удаленного репозитория и объединяет их с вашей локальной копией.
- Сервисы хостинга Git хранят репозитории и часто предоставляют функции отслеживания проблем, ревью кода и автоматизированной сборки. Они удобны, но это не сам Git — Git работает отлично и без них.
Для публикации новой записи с помощью Git из терминала требуется четыре команды. Первая выполняется только один раз на проект; остальные три — это ежедневная последовательность действий: подготовка файла к отправке, создание его снимка и отправка на удаленный репозиторий.
git init # turn this folder into a repository (once)
git add posts/new-post.md # stage the file for your next commit
git commit -m "Add new post" # save a snapshot with a message
git push # copy your commits to the remoteCopy
На практике команда git push работает только после настройки удаленного репозитория, например с помощью команды git remote add origin <url>, и при первом отправлении изменений в ветку обычно требуется использовать команду git push -u origin main или аналогичную. После этого достаточно просто использовать команду git push.
Откуда появились генераторы статических сайтов
Когда уже есть соответствующая терминология, история развития становится более понятной, поскольку каждое новое поколение инструментов добавляло одну из вышеупомянутых концепций.
Разделение процесса написания кода и форматирования контента существовало задолго до появления термина «генератор статических сайтов». HSC, сокращение от «HTML Sucks Completely», — это препроцессор HTML, выпущенный Томасом Аглассингером в 1996 году. Он уже поддерживал функции включения файлов, условные операторы и проверку ссылок примерно за десять лет до того, как у этой категории появилось название.
В конце 1990-х и 2000-х годах большинство людей, желавших создать блог, выбирали хостинговые динамические сервисы вроде Blogger, LiveJournal или Open Diary, либо устанавливали программное обеспечение с базой данных, такое как WordPress. Movable Type — платформа на языке Perl, созданная Беном и Меной Тротт в 2001 году, пошла другим путем: каждый раз при публикации через её веб-интерфейс блог преобразовывался в обычные статические HTML-файлы. Пользователи никогда не пользовались терминалом, однако читатели получали статические страницы. Это позволило людям, которые никогда бы не ввели команду сборки, воспользоваться преимуществами статического вывода.
Nanoc появился в 2007 году; его создал Денис Дефрейн после того, как системы управления контентом Ruby оказались слишком медленными на его виртуальном сервере объемом 96 МБ. Он ввел возможность использования шаблонов, метаданных для каждой страницы, поддержку Markdown и плагины. В декабре 2008 года сооснователь GitHub Том Престон-Вернер выпустил Jekyll, руководствуясь недовольством тяжелыми движками для ведения блогов. Jekyll опирался на идеи Nanoc и добавил два ключевых элемента: YAML-метаданные в начале каждого файла с контентом и возможность работы как блог без дополнительной настройки, так что папка с файлами Markdown автоматически превращалась в блог. Разработанная одновременно с ним GitHub Pages предоставляла бесплатное статическое хостинговое решение, и именно это сочетание в большей степени, чем что-либо еще, способствовало популяризации SSG.
Почти всё, что появилось после этого, представляет собой переосмысление того же подхода на других языках. Octopress, разработка которого прекращена, и Middleman продолжили линейку инструментов на Ruby. Pelican основан на Python, а Hyde развивается на базе Laravel.
В июле 2013 года Стив Франчия выпустил Hugo — программу на языке Go, распространяемую в виде единого скомпилированного бинарника. По сравнению с Jekyll не требовалась установка среды Ruby и согласование версий библиотек gem, а скорость сборки, измеряемая в секундах даже для сайтов с тысячами страниц, стала его отличительной чертой.
В конце 2017 года Зак Лезерман выпустил Eleventy (11ty) — гибкую альтернативу Jekyll, работающую на JavaScript и устанавливаемую через npm. Jekyll привязывает к использованию языка Liquid; Eleventy поддерживает множество форматов шаблонов:
- форматы маркиупа и контента: обычный HTML (
.html), Markdown (.md) и MDX (.mdx)
.11ty.js, TypeScript (.ts), JSX (.jsx) и WebC (.webc).njk), Handlebars (.hbs), Mustache, EJS, Haml и Pug.scss)Некоторые из этих форматов требуют дополнительных плагинов или настройок, чтобы работать без изменений, поэтому перед использованием обязательно ознакомьтесь с актуальной документацией Eleventy. Если вы уже знаете определенный язык программирования, каталог генераторов на Jamstack.org позволяет отфильтровать инструменты, написанные на этом языке.
Многие генераторы в той папке не обновлялись уже много лет, и для личного сайта это часто допустимо. Статический сайт не содержит кода с серверной стороны или базы данных, доступных посетителям, что устраняет наиболее распространенные поводы для атак, характерные для динамических блогов. Если новая версия вашего генератора добавляет функции, которые вам не нравятся, вы можете продолжать использовать старую версию — она будет продолжать генерировать тот же сайт. Однако следует помнить, что «отсутствие обновлений» не означает «отсутствие рисков»: зависимости, используемые при сборке, машина, на которой происходит сборка, и любые сторонние скрипты JavaScript, которые вы встраиваете, по-прежнему требуют внимания; к тому же необслуживаемый инструмент со временем может перестать корректно устанавливаться на более новую операционную систему или среду выполнения языка.
Git решает две проблемы, но вам не нужен ни один из них
Руководства для начинающих почти всегда советуют использовать Git. Это отчасти связано с привычкой разработчиков, но отчасти — с историей: Jekyll, первый широко используемый SSG, изначально был проектом на GitHub. Хостинг на GitHub, Codeberg или GitLab отвечает на вопрос «Где находятся мои файлы?» ответом «В репозитории». Сервисы вроде Neocities или Nekoweb отвечают на него иначе: вы загружаете файлы через сам сайт.
На хостинге на основе Git, таком как Codeberg Pages или GitLab Pages, даже изменения, внесенные через веб-интерфейс, становятся коммитами и отправляются в репозиторий в фоновом режиме. Вы используете Git независимо от того, печатали ли вы когда-либо команды Git или нет.
Если вы сами хостите сайт, файлы находятся на вашем собственном компьютере, обычно в каталоге вроде /var/www/html в Linux. На общедоступном сервере, таком как сервер Tildeverse, они находятся в публичной папке вашего аккаунта; распространенным подходом здесь является сборка кода локально, а затем использование rsync для копирования результата на общедоступный компьютер, где он автоматически предоставляется пользователям.
В таких конфигурациях полезно разделять две основные функции Git:
- хранение истории версий, что позволяет отменить некорректные изменения и увидеть, что и когда было изменено
- перенос готовых файлов в место, откуда они предоставляются пользователям
Ни для одной из этих задач строго не требуется Git. rsync, клиент FTP или форма загрузки в браузере прекрасно подходят для публикации сайта, а обычные резервные копии могут заменить историю изменений в небольших личных проектах. Git популярен потому, что он позволяет выполнять обе задачи одновременно, не стоит ничего и работает с бесплатным хостингом, что делает его наиболее простым решением, а не обязательным условием.
Разница между идеальной схемой и реальной реализацией
На бумаге архитектура генератора блогов кажется почти до скуки простой:
- статьи хранятся в виде файлов Markdown в папке
posts/ - шаблон в папке
layout/отображает их содержимое - этот шаблон собирает фрагменты HTML из папки
partials/, такие какheader.htmlиfooter.html
config.yml (или эквивалентный) в корне проекта содержит параметры для всего сайта, такие как название или цвета"2024-03-14-my-post-title.md"То, что не показано на диаграмме, — это внутренние механизмы. Преобразование этих папок в готовый сайт, например, в папке _site/, требует среды выполнения программного языка для запуска генератора, и каждый звенье в этой цепочке может стать причиной сбоев.
Популярные инструменты стараются скрыть этот процесс за одним командным приказом, таким как hugo build или npx @11ty/eleventy --serve. Параметр --serve в команде Eleventy запускает локальный сервер разработки и пересоздаёт сайт каждый раз при сохранении исходного файла, вместо того чтобы собрать его один раз и завершить работу. Именно такой быстрый цикл обратной связи делает редактирование статического сайта почти таким же мгновенным, как редактирование живой страницы.
Платформы развертывания применяют ту же идею к облакам. Netlify или самостоятельно хостируемый Coolify выполняют сборку на удаленном компьютере, определяют используемый генератор, запускают соответствующую команду и публикуют папку с результатами по адресу вроде yoursitename.netlify.app. Концептуально это аналогично загрузке вручную написанного HTML на Neocities и получению адреса yoursitename.neocities.org, только сборка происходит на их сервере. Похожие решения предлагают surge.sh, GitHub Pages, Vercel, а также сервис Pages от Cloudflare; выбор зависит от того, насколько важны для вас удобство по сравнению с независимостью от крупных платформ. Если вы хотите увидеть полный процесс развертывания от начала до конца, наш обзор развертывания небольшого веб-сайта на Cloudflare показывает конкретный пример.
Почему одна лишняя запятая может всё испортить
Каждый из этих удобств основан на предположениях: ваши файлы корректны, среда выполнения языка установлена правильно, и вы хорошо разбираетесь в терминале. Разработчики часто преувеличивают распространённость последнего навыка, что хорошо показано в этой карикатуре XKCD.
Процесс сборки также крайне чувствителен. Одна небольшая ошибка синтаксиса в важном файле, даже такая мелкая, как лишняя запятая, может полностью остановить установку или сборку. Что ещё хуже, сообщение об ошибке обычно поступает от самой среды выполнения или парсера, а не от генератора, поэтому оно формулируется с учётом особенностей программировочного языка, а не вашего сайта. Реалистичный пример: файл данных в формате JSON с лишней запятой после последнего свойства приводит к сбою сборки в Netlify, при этом трейс ошибки парсера никогда не упоминает сам файл, изложенный простым языком для начинающих.
Столкнувшись с подобным результатом, многие люди разумно решают писать HTML вручную, перейти на хостинговый CMS или вообще отказаться от создания сайта. Последний вариант — настоящая потеря. Несколько привычек снижают вероятность этого:
- запускайте процесс сборки локально с помощью разработческого сервера перед публикацией, чтобы сбои сначала появлялись на вашем экране
- меняйте по одной вещи за раз, чтобы при возникновении проблем самой последней изменением было легко заняться
- читайте сообщение об ошибке снизу вверх и ищите имя файла и номер строки — это обычно является настоящей зацепкой
- проверяйте JSON и YAML с помощью расширения для редактора или инструмента линтеринга, поскольку именно эти форматы вызывают большинство ошибок у начинающих при сборке
- часто сохраняйте рабочие версии, чтобы всегда можно было вернуться к последней успешно собранной версии
Обучение путем модификации шаблона-стартера
Проверенным способом изучения генераторов контента является использование готовых стартовых проектов или шаблонов: начинаете с них, постепенно вносите изменения и разбираете каждый файл, пока не поймёте их структуру. Со временем вы наберётесь знаний, чтобы создать свой проект с нуля. Хорошие стартовые проекты для этой цели обладают несколькими особенностями: чёткой документацией, небольшим количеством файлов и одним явным местом для размещения контента и настроек. Типичные примеры выглядят следующим образом:
- стартовый проект Hugo, в котором статьи хранятся в папке
/post, а настройки сайта — в файлеhugo.toml; при необходимости могут использоваться функции IndieWeb, такие как microformats2 и заранее подготовленные h-card - стартовый проект Eleventy, где статьи находятся в папке
/posts, а информация о сайте — в файле данных, напримерsite.js - стартовый проект Jekyll, в котором статьи хранятся в папке
/_posts, а настройки — в файле_config.yml
Намеренно простые стартовые решения являются преимуществом для обучения. Когда стилизация минимальна, структура легко различима, и вся работа по дизайну остается на вас.
Крошечные генераторы с практически отсутствующими движущимися частями
Hugo, Eleventy и Jekyll — популярные варианты, но существует целая серия очень маленьких генераторов для тех, кто хочет понять весь инструмент за один день.
- barf, сокращение от «blogs are really fun», — это скрипт оболочки длиной примерно 170 строк, созданный btxx на основе проекта Karl Bartel’s blog.sh. В нем отсутствуют вступительные данные и шаблоны. Вы пишете файлы в формате Markdown, запускаете команду
make build, а затем с помощью rsync загружаете полученную папкуbuild/. RSS-ленты генерируются автоматически; скрипт корректно работает на OpenBSD, macOS и Linux, а его стилишит состоит из четырех строк. В файле README и в примере реальной работы показано, как выглядит итоговый результат.
bb.sh, состоящий примерно из 1 000 строк, который не требует никаких дополнительных зависимостей, кроме стандартных утилит Unix таких как date, grep, sed и head. Первую версию написал Карлос Феноллоса в 2011 году, объяснив подход в одной из своих блог-статей; на момент написания этого текста проект по-прежнему поддерживался. Как только bb.sh окажется в публичной директории вашего сервера, команда ./bb.sh post создаст новую запись. Работа с черновиками, тегами, форматом Markdown и RSS осуществляется без необходимости в какой-либо установке. Сообщество создало форк под названием bashblog-ng, добавивший дополнительные функции.Ещё несколько инструментов, о которых стоит знать:
- ssg — это шелл-скрипт, соответствующий стандарту POSIX, разработанный Roman Zolotarev; он послужил основой для нескольких инструментов из этого списка; pyssg — это переписанная версия на Python.
- sw, написанный на C, — это преднамеренно минималистичная веб-фреймворк, а его форк simple-static делает его ещё проще, превращая его, как описано в README, в самый простой генератор статических сайтов, который только мог представить его разработчик.
- makesite.py — это аналог barf и bashblog для Python, состоящий из менее чем 130 строк; его создала Сунайна Пай, исходя из принципа, что сам код является документацией. Конфигурационного слоя нет; вы читаете скрипт и редактируете его напрямую.
Ни один из этих инструментов не приближается по функционалу к Hugo или Eleventy, и именно в этом заключается смысл. То, что они теряют в плане плагинов и форматов шаблонов, они компенсируют прозрачностью: когда что-то ломается, весь код помещается на экране.
Если вы готовы полностью отойти от веба, публикация через протокол Gemini — ещё один вариант. Страницы Gemini используют простой текстовый формат, который передаётся без изменений, поэтому часто вообще не требуется ничего генерировать.
Основные выводы
- Сначала научитесь писать страницы вручную; генератор автоматизирует процесс повторения, который вы уже должны понимать.
- Большинство недопониманий в отношении SSG связаны с лексикой. Как только станут ясны понятия исходного кода, результата, процесса сборки, макета, частичных элементов и вступительной информации, документация любого инструмента будет казаться похожей.
- Макеты, частичные элементы и глобальные файлы данных существуют для того, чтобы изменения, внесённые один раз, отразились везде при следующей сборке.
- Git обеспечивает историю изменений и способ публикации, но rsync, FTP или загрузка через браузер также являются подходящими альтернативами для личного сайта.