Create React App

Для интеграции MDX в проект на базе Create React App (CRA) требуется установить несколько ключевых зависимостей. MDX позволяет писать JSX внутри Markdown-файлов, что делает документацию и контент более интерактивным.

Основные шаги установки:

npm install @mdx-js/react @mdx-js/loader

Для поддержки загрузки .mdx файлов через webpack в CRA потребуется либо настройка react-app-rewired, либо использование craco для обхода ограничения на прямую конфигурацию webpack.

Пример конфигурации с использованием craco:

  1. Установить craco и необходимые плагины:
npm install @craco/craco craco-mdx
  1. Создать файл craco.config.js:
const CracoMdxPlugin = require('craco-mdx');

module.exports = {
  plugins: [
    {
      plugin: CracoMdxPlugin,
      options: {
        extension: /\.mdx?$/
      }
    }
  ]
};
  1. Обновить скрипты в package.json:
"scripts": {
  "start": "craco start",
  "build": "craco build",
  "test": "craco test"
}

После этого проект CRA будет корректно обрабатывать MDX-файлы.


Использование MDXProvider

MDXProvider из @mdx-js/react позволяет переопределять стандартные компоненты Markdown, такие как

,

или . Это обеспечивает единый стиль и возможность добавления кастомного поведения.

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

import { MDXProvider } from '@mdx-js/react';

const components = {
  h1: (props) => 

, a: (props) => }; function App({ children }) { return ( {children} ); }

Все MDX-файлы внутри будут использовать кастомные компоненты, заданные в объекте components.


Импорт и рендеринг MDX файлов

MDX-файлы можно импортировать напрямую в React-компоненты после настройки загрузчика:

import MyDocument from './docs/MyDocument.mdx';

function App() {
  return (
    
); }

MDX автоматически транслируется в React-компоненты, а внутри файлов можно использовать как Markdown, так и JSX:

# Заголовок первого уровня

Текст с **жирным** форматированием.


Динамический импорт MDX

Для больших проектов удобно загружать MDX-файлы динамически с помощью React.lazy и Suspense:

import React, { Suspense, lazy } from 'react';

const LazyMDX = lazy(() => import('./docs/LazyDocument.mdx'));

function App() {
  return (
    Загрузка...

}> ); }

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


Расширенные возможности MDX

  • Кастомные компоненты: любые React-компоненты можно использовать внутри MDX. Это позволяет строить интерактивную документацию или страницы с UI-компонентами.
  • Переменные и контекст: внутри MDX можно использовать контексты React, передавая данные и состояния.
  • Стилизация: поддерживаются любые CSS-методы: CSS Modules, Styled Components, Tailwind, Emotion и др.
  • Плагины Remark и Rehype: MDX поддерживает расширение Markdown через плагины для синтаксиса, форматирования кода, обработки изображений и ссылок.

Пример подключения плагина remark-gfm для поддержки GitHub Flavored Markdown:

import { MDXProvider } from '@mdx-js/react';
import remarkGfm from 'remark-gfm';


  

Организация файловой структуры

Рекомендуется разделять MDX-файлы по назначению:

src/
├─ docs/
│  ├─ Introduction.mdx
│  ├─ Components.mdx
├─ components/
│  ├─ Button.jsx
│  ├─ Card.jsx

Такой подход облегчает поддержку, поиск и повторное использование контента.


Работа с навигацией и роутингом

MDX легко интегрируется с react-router для создания многостраничной документации:

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './docs/Home.mdx';
import About from './docs/About.mdx';

function App() {
  return (
    
      
        } />
        } />
      
    
  );
}

Каждый MDX-файл становится полноценной страницей с возможностью использования всех React-функций.


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

  • Кэширование MDX: при большом количестве файлов рекомендуется предварительно транслировать MDX в JavaScript при сборке, чтобы уменьшить время загрузки.
  • Lazy Loading: использование React.lazy и Suspense позволяет подгружать MDX только при необходимости.
  • Минификация и tree-shaking: при правильной сборке MDX не увеличивает размер бандла больше, чем нужно.