Rollup плагины

Remark и Rehype — это экосистемы плагинов для обработки Markdown и HTML в JavaScript. Они позволяют трансформировать и анализировать контент, предоставляя высокую гибкость для сборки и компиляции документации, статических сайтов и других текстовых проектов. В интеграции с Rollup эти библиотеки становятся мощным инструментом для создания современных сборок.


Основы интеграции с Rollup

Rollup — это модульный сборщик, ориентированный на работу с ES-модулями. Он использует плагины для расширения функциональности при обработке файлов различных типов. Для работы с Markdown и HTML используются плагины, которые обрабатывают файлы через Remark и Rehype, а затем преобразуют их в JavaScript-модули.

Простейшая интеграция выглядит так:

import { remark } from 'remark';
import remarkHtml from 'remark-html';
import { createFilter } from '@rollup/pluginutils';

export default function rollupRemark(options = {}) {
  const filter = createFilter(options.include, options.exclude);

  return {
    name: 'rollup-remark',
    async transform(code, id) {
      if (!filter(id)) return null;

      const result = await remark().use(remarkHtml).process(code);
      return {
        code: `export default ${JSON.stringify(String(result))};`,
        map: { mappings: '' },
      };
    },
  };
}

Ключевые моменты:

  • createFilter позволяет ограничивать обработку только нужными файлами (.md, .markdown).
  • remark().use(plugin) подключает плагины для трансформации Markdown.
  • Результат process возвращается как HTML, который затем экспортируется как строка JS-модуля.

Основные плагины Remark для Rollup

  1. remark-html Преобразует Markdown в HTML. Часто используется как конечный шаг в цепочке трансформаций.

  2. remark-slug Генерирует уникальные идентификаторы для заголовков (<h1>, <h2> и т.д.), что удобно для генерации ссылок на секции.

  3. remark-autolink-headings Добавляет ссылку к каждому заголовку, чтобы пользователи могли легко копировать URL к определённой секции документа.

  4. remark-toc Автоматически создаёт оглавление на основе структуры Markdown-документа.

  5. remark-prism или remark-highlight.js Добавляют подсветку синтаксиса для блоков кода.

Пример подключения нескольких плагинов:

remark()
  .use(remarkSlug)
  .use(remarkAutolinkHeadings, { beh * avior: 'wrap' })
  .use(remarkHtml)

Rehype и обработка HTML

Rehype работает на уровне HTML и позволяет делать глубокие трансформации DOM-подобной структуры. Основное отличие от Remark — работа уже с HTML, а не с Markdown.

Популярные плагины Rehype:

  • rehype-stringify — преобразует AST HTML обратно в строку.
  • rehype-parse — парсит HTML в AST, часто используется для обработки внешнего HTML-контента.
  • rehype-slug и rehype-autolink-headings — аналогично Remark, но для HTML.
  • rehype-prism-plus — подсветка кода на основе Prism.js.

Пример цепочки с Rehype:

import { rehype } from 'rehype';
import rehypeParse from 'rehype-parse';
import rehypeSlug from 'rehype-slug';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import rehypeStringify from 'rehype-stringify';

const result = await rehype()
  .use(rehypeParse, { fragment: true })
  .use(rehypeSlug)
  .use(rehypeAutolinkHeadings, { beh * avior: 'append' })
  .use(rehypeStringify)
  .process('<h1>Заголовок</h1>');

Интеграция Remark + Rehype

Часто Markdown сначала обрабатывается через Remark, а затем HTML-трансформации выполняются через Rehype. Это обеспечивает полный контроль над текстом и его визуальным представлением.

import { remark } from 'remark';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';

const result = await remark()
  .use(remarkRehype) // Преобразование AST Markdown в AST HTML
  .use(rehypeStringify) // Генерация строки HTML
  .process(markdownContent);

Особенности работы:

  • remark-rehype конвертирует Markdown AST в HTML AST.
  • Можно добавлять Rehype-плагины для модификации HTML перед генерацией строки.

Настройка Rollup для комплексной обработки Markdown

Для удобной работы рекомендуется создавать отдельный Rollup-плагин, который объединяет Remark и Rehype. Пример структуры:

import { remark } from 'remark';
import remarkRehype from 'remark-rehype';
import rehypeSlug from 'rehype-slug';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import rehypeStringify from 'rehype-stringify';
import { createFilter } from '@rollup/pluginutils';

export default function markdownPlugin(options = {}) {
  const filter = createFilter(options.include || '**/*.md', options.exclude);

  return {
    name: 'markdown',
    async transform(code, id) {
      if (!filter(id)) return null;

      const result = await remark()
        .use(remarkRehype)
        .use(rehypeSlug)
        .use(rehypeAutolinkHeadings, { beh * avior: 'wrap' })
        .use(rehypeStringify)
        .process(code);

      return {
        code: `export default ${JSON.stringify(String(result))};`,
        map: { mappings: '' },
      };
    },
  };
}

Такой подход позволяет:

  • Поддерживать единую точку конфигурации плагинов.
  • Легко добавлять новые трансформации Markdown и HTML.
  • Генерировать готовый HTML-контент как модуль для импорта в JavaScript.

Особенности использования

  • Rollup выполняет трансформацию файлов во время сборки, поэтому все плагины Remark/Rehype должны работать синхронно или возвращать Promise для асинхронной обработки.
  • AST (Abstract Syntax Tree) используется как промежуточное представление для всех преобразований.
  • Плагины можно комбинировать в цепочки, но порядок подключения влияет на конечный результат. Например, slug-плагины должны применяться перед autolink-плагинами, чтобы ссылки корректно генерировались.
  • Для больших проектов рекомендуется кешировать результат трансформации, чтобы ускорить повторные сборки.

Практические советы

  • Для проектов с документацией на Markdown стоит использовать remark-toc, remark-slug и Rehype-плагины для ссылок на заголовки.
  • Для сайтов с подсветкой кода удобны remark-prism или rehype-prism-plus.
  • Комбинирование Remark и Rehype дает возможность сначала обрабатывать контент логически (Markdown), а затем визуально (HTML), сохраняя структуру и стилизацию.

Хотя интеграция Remark и Rehype с Rollup требует внимательной настройки плагинов, она обеспечивает гибкость и позволяет создавать кастомные сборки с полной поддержкой Markdown и HTML, готовые к использованию в современных веб-приложениях.