Сборка статических сайтов с unified

Библиотека unified является ядром экосистемы для обработки текстовых форматов в JavaScript. Она предоставляет единый интерфейс для построения пайплайнов обработки данных: от парсинга исходного текста до генерации HTML или других форматов. Основной принцип работы unified заключается в создании цепочек плагинов, каждый из которых выполняет определённую задачу.

Remark — это плагин для unified, предназначенный для работы с Markdown. Он обеспечивает парсинг Markdown в дерево MDAST (Markdown Abstract Syntax Tree), которое представляет структуру документа в виде объектов JavaScript. Remark позволяет анализировать, модифицировать и генерировать Markdown-контент, добавлять плагины для проверки ссылок, подсветки кода и других задач.

Rehype аналогичен Remark, но работает с HTML. Он оперирует деревом HAST (HTML Abstract Syntax Tree), предоставляя мощные средства для трансформации HTML-документов и интеграции с другими инструментами.

Установка и базовая конфигурация

Для начала работы требуется установка пакетов:

npm install unified remark-parse remark-stringify rehype rehype-stringify

Пример создания простого пайплайна для обработки Markdown:

import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';

const processor = unified()
  .use(remarkParse)      // Парсинг Markdown в MDAST
  .use(remarkStringify); // Генерация Markdown из MDAST

const markdown = '# Заголовок\n\nТекст абзаца';
const result = processor.processSync(markdown);
console.log(String(result));

В этом примере Markdown преобразуется в дерево MDAST и обратно в строку Markdown. Такой подход обеспечивает возможность промежуточной обработки документа.

Работа с плагинами

Плагины в unified выполняют роль промежуточной обработки дерева. Например, можно добавить подсветку синтаксиса для блоков кода:

import remarkPrism from 'remark-prism';

const processor = unified()
  .use(remarkParse)
  .use(remarkPrism)      // Добавляет подсветку синтаксиса
  .use(remarkStringify);

Каждый плагин может получать конфигурацию. Remark поддерживает как плагины для анализа документа (linting), так и для трансформации (например, автогенерация оглавления).

Конвертация Markdown в HTML

Для генерации статических сайтов часто необходимо преобразовать Markdown в HTML. Это делается с помощью сочетания Remark и Rehype:

import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';

const processor = unified()
  .use(remarkParse)
  .use(remarkRehype)    // Конвертация MDAST в HAST
  .use(rehypeStringify); // Генерация HTML из HAST

const markdown = '# Заголовок\n\nТекст абзаца';
const html = processor.processSync(markdown);
console.log(String(html));

remark-rehype выполняет ключевую роль, переводя структуру Markdown в дерево HTML. После этого Rehype может применить дополнительные плагины для оптимизации HTML, добавления классов, атрибутов или минификации.

Настройка пайплайна для статического сайта

Для статического сайта обычно требуется:

  1. Парсинг Markdown файлов с контентом.
  2. Преобразование в HTML с возможностью добавления кастомных атрибутов, классов, таблиц контента.
  3. Интеграция с шаблонами (например, Handlebars или EJS) для оборачивания HTML страниц в общий дизайн.
  4. Минификация и оптимизация HTML для уменьшения размера файлов.

Пример расширенного пайплайна:

import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import rehypeHighlight from 'rehype-highlight';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import fs from 'fs';

const markdownFiles = ['index.md', 'about.md'];

markdownFiles.forEach(file => {
  const markdown = fs.readFileSync(file, 'utf-8');

  const html = unified()
    .use(remarkParse)
    .use(remarkRehype)
    .use(rehypeHighlight)          // Подсветка синтаксиса
    .use(rehypeAutolinkHeadings)   // Автогенерация ссылок на заголовки
    .use(rehypeStringify)
    .processSync(markdown);

  fs.writeFileSync(file.replace('.md', '.html'), String(html));
});

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

Преимущества использования unified для сборки сайтов

  • Модульность: легко подключать плагины для любой стадии обработки.
  • Гибкость: можно обрабатывать Markdown, HTML и любые другие текстовые форматы.
  • Стандартизированное дерево: MDAST и HAST обеспечивают единый формат данных для трансформаций.
  • Интеграция с другими инструментами: поддержка плагинов для линтинга, SEO, генерации таблиц контента, минификации HTML.

Дополнительные техники

  • Кастомные трансформации: можно писать собственные плагины для изменения дерева MDAST/HAST, например, для вставки специальных блоков или баннеров.
  • Объединение с CSS и JS: после генерации HTML можно интегрировать его с шаблонами и подключить стили и скрипты.
  • Инкрементальная генерация: для больших сайтов оптимально обрабатывать только изменённые Markdown файлы, снижая время сборки.

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