MDX — это расширение Markdown, позволяющее интегрировать JSX прямо в Markdown-документы. Архитектура MDX построена на модульной системе обработки контента, где ключевую роль играют плагины. Плагины обеспечивают возможность расширения функциональности на каждом этапе компиляции: от синтаксического анализа до генерации конечного JavaScript-кода.
MDX использует три основных типа плагинов: плагины для парсинга, плагины для трансформации и плагины для компиляции. Их совместная работа обеспечивает гибкость и расширяемость библиотеки.
На этом этапе происходит чтение исходного Markdown/MDX-кода и преобразование его в AST (Abstract Syntax Tree). MDX использует систему парсеров из экосистемы remark и rehype:
Основная задача парсера — создать корректное дерево синтаксических элементов, которое затем передается на этап трансформации.
Пример подключения плагина для remark:
import { compile } from '@mdx-js/mdx';
import remarkGfm from 'remark-gfm';
const mdxContent = `
# Заголовок
- Список
`;
const result = await compile(mdxContent, {
remarkPlugins: [remarkGfm],
});
remarkGfm добавляет поддержку расширений GitHub Flavored
Markdown (GFM) — таблицы, зачеркивания, задачи.
После построения AST применяется этап трансформации. Здесь rehype-плагины и некоторые специализированные MDX-плагины могут изменять дерево. Возможные операции включают:
Пример плагина, который добавляет класс к каждому параграфу:
import rehypePlugin from 'rehype';
function addParagraphClass() {
return (tree) => {
visit(tree, 'element', (node) => {
if (node.tagName === 'p') {
node.properties = node.properties || {};
node.properties.className = ['custom-paragraph'];
}
});
};
}
Здесь используется visit из библиотеки
unist-util-visit, чтобы обойти дерево и применить изменения
к нужным элементам.
На последнем этапе MDX-трансформированное дерево AST конвертируется в JavaScript/JSX-код. Компиляторы MDX используют плагины для:
Пример добавления глобального импорта через плагин:
import { compile } from '@mdx-js/mdx';
const result = await compile(mdxContent, {
providerImportSource: '@mdx-js/react',
remarkPlugins: [],
rehypePlugins: [],
});
Параметр providerImportSource автоматически добавляет
импорт MDXProvider, который позволяет использовать
собственные компоненты для тегов Markdown.
unified, поэтому их можно
использовать без модификаций.MDX-плагин — это функция, принимающая AST и опции и возвращающая изменённое дерево:
function myMdxPlugin(options = {}) {
return (tree, file) => {
// Пример: добавить атрибут data-type ко всем заголовкам h2
visit(tree, 'element', (node) => {
if (node.tagName === 'h2') {
node.properties = node.properties || {};
node.properties['data-type'] = options.type || 'default';
}
});
};
}
Плагин может быть гибким благодаря параметрам, передаваемым через
options.
Плагины работают по принципу цепочки обработки:
Такое разделение позволяет:
unified для Markdown
и HTML.