В контексте MDX под макросом понимается механизм, позволяющий создавать повторно используемые конструкции, которые преобразуются в стандартный JSX во время компиляции. Макросы помогают избегать дублирования кода, структурируют контент и позволяют внедрять динамические элементы в Markdown-документы.
Синтаксис макросов в MDX может быть реализован через функции, экспортируемые из внешних файлов:
// macros.js
export function Highlight({ children, color = 'yellow' }) {
return <span style={{ backgroundColor: color }}>{children}</span>;
}
Использование макроса в MDX:
import { Highlight } from './macros'
Это пример текста с <Highlight color="lightgreen">выделением</Highlight>.
Ключевой момент: макросы обрабатываются как обычные React-компоненты, но позволяют внедрять стилизованные и динамичные фрагменты Markdown без лишнего кода.
MDX позволяет применять преобразования к содержимому через Remark-плагины и Rehype-плагины, что обеспечивает гибкую трансформацию Markdown перед рендерингом в JSX.
Remark работает на уровне синтаксического дерева
Markdown (MDAST), позволяя:
Пример подключения плагина для добавления нумерации заголовков:
import remarkSlug from 'remark-slug';
import remarkAutolinkHeadings from 'remark-autolink-headings';
const mdxOptions = {
remarkPlugins: [remarkSlug, remarkAutolinkHeadings],
};
Rehype работает на уровне HTML-дерева (HAST), что
позволяет:
Пример применения Rehype-плагина для автоматического добавления
target="_blank" к внешним ссылкам:
import rehypeExternalLinks from 'rehype-external-links';
const mdxOptions = {
rehypePlugins: [[rehypeExternalLinks, { target: '_blank', rel: ['noopener'] }]],
};
MDX поддерживает комбинацию макросов и плагинов для сложных трансформаций. Например, можно создать макрос, который автоматически оборачивает блоки кода в компонент с подсветкой синтаксиса:
// CodeBlock.js
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/esm/styles/prism';
export default function CodeBlock({ className, children }) {
const language = className?.replace('language-', '') || 'text';
return <SyntaxHighlighter language={language} style={dark}>{children}</SyntaxHighlighter>;
}
Использование макроса в MDX:
import CodeBlock from './CodeBlock'
<CodeBlock className="language-js">
{`console.log("Hello, MDX!");`}
</CodeBlock>
Эта комбинация позволяет:
MDX позволяет создавать макросы не только как отдельные компоненты, но и как функции, возвращающие JSX на основе параметров. Это открывает возможности для генерации сложного контента на лету:
export function Alert({ type = 'info', children }) {
const colors = { info: 'blue', warning: 'orange', error: 'red' };
return <div style={{ borderLeft: `4px solid ${colors[type]}`, padding: '10px' }}>{children}</div>;
}
Применение:
<Alert type="warning">Это предупреждение!</Alert>
Преобразования могут быть встроены в макросы для автоматической фильтрации, изменения или форматирования содержимого перед его отображением.
MDXProvider позволяет глобально переопределять стандартные Markdown-элементы. В сочетании с макросами это дает мощный инструмент для унификации стиля:
import { MDXProvider } from '@mdx-js/react';
import { Highlight, CodeBlock } from './macros';
const components = {
h1: (props) => <h1 style={{ color: 'darkblue' }} {...props} />,
code: CodeBlock,
span: Highlight
};
<MDXProvider components={components}>
<MDXContent />
</MDXProvider>
Преимущества:
h1, code и span в
документации автоматически получают единый стиль.Эти подходы обеспечивают масштабируемость, поддерживаемость и удобство сопровождения большого объема документации или учебного контента.