Порядок применения плагинов

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

Основные этапы обработки MDX

Процесс компиляции MDX можно разделить на несколько последовательных шагов:

  1. Парсинг Markdown Исходный файл сначала обрабатывается Markdown-парсером, обычно remark-parse. На этом этапе текст превращается в дерево узлов MDAST (Markdown Abstract Syntax Tree). Плагины для Markdown (remark-плагины) применяются к этому дереву до того, как оно будет преобразовано в JSX. Порядок подключения плагинов здесь имеет значение: плагины, изменяющие структуру заголовков или параграфов, должны идти перед плагинами, добавляющими новые синтаксические элементы.

  2. Преобразование в HAST (HTML AST) После применения remark-плагинов MDAST преобразуется в HAST с помощью remark-rehype. Этот этап позволяет работать с HTML-подобной структурой документа. На этом этапе подключаются rehype-плагины, которые могут выполнять:

    • добавление или изменение атрибутов HTML-элементов;
    • вставку дополнительных компонентов;
    • оптимизацию структуры DOM. Плагины, которые добавляют новые элементы в дерево, должны применяться до плагинов, работающих с уже существующими элементами, иначе новые узлы могут быть проигнорированы.
  3. Компиляция в JSX На заключительном этапе HAST преобразуется в JSX. Здесь можно использовать плагины @mdx-js/mdx для модификации финального AST, добавления экспорта компонентов или обертывания содержимого в обертки.

Влияние порядка плагинов

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

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

Пример конфигурации

import { createCompiler } from '@mdx-js/mdx';
import remarkGfm from 'remark-gfm';
import remarkSlug from 'remark-slug';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import rehypeHighlight from 'rehype-highlight';

const compiler = createCompiler({
  remarkPlugins: [
    remarkGfm,       // Поддержка GitHub-flavored Markdown
    remarkSlug       // Генерация id для заголовков
  ],
  rehypePlugins: [
    rehypeHighlight,        // Подсветка кода
    rehypeAutolinkHeadings  // Автоссылки на заголовки
  ]
});

В этом примере порядок важен: remarkSlug должен идти после всех изменений заголовков, чтобы генерировать корректные идентификаторы. rehypeAutolinkHeadings должен применяться после rehypeHighlight, иначе ссылки могут быть вставлены в некорректно обработанный код.

Рекомендации по построению пайплайна

  • Группировка по этапам: разделять плагины на remark и rehype, чтобы избежать конфликтов между Markdown и HTML AST.
  • Проверка взаимодействия: тестировать плагины парами, особенно если один модифицирует структуру, а другой форматирует элементы.
  • Использование встроенных оберток: для сложных изменений JSX рекомендуется использовать MDXProvider или добавлять собственные wrapper-компоненты через плагины на этапе компиляции.

Отладка порядка

MDX позволяет выводить промежуточные AST деревья. Это помогает понять, на каком этапе плагины применяются и как они изменяют структуру:

import { compile } from '@mdx-js/mdx';
import remarkParse from 'remark-parse';

const result = await compile('# Заголовок\n\nТекст', {
  remarkPlugins: [remarkParse],
  outputFormat: 'mdx'
});

console.log(result.value);

Отображение промежуточных деревьев помогает выявить ошибки в порядке плагинов и корректировать их до финальной сборки.

Итоговая логика

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

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