MDX — это расширение Markdown, которое позволяет встраивать
JSX-компоненты непосредственно в текстовые документы. Для работы с MDX в
среде JavaScript необходимо установить пакет @mdx-js/mdx и,
при использовании React, @mdx-js/react. Установка
выполняется через npm или yarn:
npm install @mdx-js/mdx @mdx-js/react
После установки можно сконфигурировать MDX для компиляции файлов
.mdx в JSX. В Node.js это делается с помощью API:
import { compile } from '@mdx-js/mdx';
import fs from 'fs';
const source = fs.readFileSync('./document.mdx', 'utf8');
const compiled = await compile(source, { outputFormat: 'function-body' });
console.log(String(compiled));
Ключевой момент:
outputFormat: 'function-body' позволяет использовать
скомпилированный код как функцию React-компонента.
MDX идеально подходит для генерации интерактивной документации и
контента с динамическими компонентами. Для рендеринга MDX в React
используется компонент MDXProvider:
import { MDXProvider } from '@mdx-js/react';
import MyComponent from './MyComponent';
const components = {
MyComponent
};
function App({ mdxContent }) {
return (
<MDXProvider components={components}>
<div>{mdxContent}</div>
</MDXProvider>
);
}
Особенность: Все JSX-компоненты, используемые внутри
MDX, должны быть зарегистрированы в объекте components. Это
обеспечивает контроль над визуальным представлением и
функциональностью.
MDX позволяет создавать документы программно, используя динамическую генерацию Markdown-контента и JSX-компонентов. Рассмотрим пример:
import fs from 'fs';
import { compile } from '@mdx-js/mdx';
const sections = [
{ title: 'Введение', content: 'Это введение в MDX.' },
{ title: 'Примеры', content: 'Здесь будут примеры использования.' }
];
let mdxContent = sections.map(
section => `## ${section.title}\n\n${section.content}\n`
).join('\n');
const compiled = await compile(mdxContent, { outputFormat: 'function-body' });
fs.writeFileSync('./generatedDocument.jsx', String(compiled));
Вывод: Можно автоматически создавать документы на основе данных из базы или API, превращая структурированные объекты в полноценный MDX-контент.
MDX поддерживает плагины для обработки синтаксиса Markdown и улучшения генерации документации. Основные типы плагинов:
remark-slug,
remark-autolink-headings).rehype-highlight, rehype-format).Пример использования плагина подсветки синтаксиса:
import { compile } from '@mdx-js/mdx';
import rehypeHighlight from 'rehype-highlight';
const source = '# Пример кода\n\n```js\nconsole.log("Hello MDX");\n```';
const compiled = await compile(source, {
rehypePlugins: [rehypeHighlight]
});
Важно: Плагины позволяют создавать полностью стилизованные и интерактивные документы без ручного вмешательства в HTML.
MDX поддерживает внедрение компонентов с передачей пропсов. Это особенно полезно для документации API или интерактивных руководств:
const mdxSource = `
# Демонстрация компонента
<MyComponent title="Пример заголовка" count={10} />
`;
import { MDXContent } from './compiledDocument.jsx';
<MDXProvider components={{ MyComponent }}>
<MDXContent />
</MDXProvider>
Преимущество: Можно генерировать документы с переменными данными, например, заголовками, таблицами, графиками, автоматически подставляемыми из JSON.
MDX-документы можно конвертировать не только в веб-страницы, но и в
PDF с помощью библиотек вроде react-pdf или
puppeteer. Общая схема:
Пример с puppeteer:
import puppeteer from 'puppeteer';
import { renderToString } from 'react-dom/server';
import { MDXProvider } from '@mdx-js/react';
import { MDXContent } from './compiledDocument.jsx';
const html = renderToString(
<MDXProvider components={{ MyComponent }}>
<MDXContent />
</MDXProvider>
);
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(html);
await page.pdf({ path: 'document.pdf', format: 'A4' });
await browser.close();
Следствие: Полная автоматизация создания PDF-документов с динамическим содержимым из исходных данных.
Эти подходы позволяют превращать MDX в инструмент для массового производства документации, интерактивных руководств и обучающих материалов с минимальными усилиями.