Vite и MDX

MDX — это расширение Markdown, позволяющее использовать JSX внутри Markdown-файлов. Благодаря этому можно создавать компоненты и страницы с динамическим содержимым, сочетая преимущества Markdown и React-компонентов. Vite обеспечивает высокую скорость разработки и сборки, что делает его идеальной платформой для работы с MDX.

Установка зависимостей

Для работы с MDX в проекте на Vite необходимо установить следующие пакеты:

npm install @mdx-js/react @mdx-js/loader vite-plugin-mdx
  • @mdx-js/react — позволяет рендерить MDX в React-приложении.
  • @mdx-js/loader — интегрирует MDX в процесс сборки.
  • vite-plugin-mdx — плагин для Vite, обеспечивающий корректную обработку MDX-файлов.

Настройка Vite для MDX

В конфигурационном файле vite.config.js необходимо подключить плагин MDX:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import mdx from 'vite-plugin-mdx';

export default defineConfig({
  plugins: [
    react(),
    mdx()
  ],
});

Это позволит Vite корректно обрабатывать файлы с расширением .mdx как полноценные React-компоненты.

Создание MDX-компонентов

MDX-файл может содержать как стандартный Markdown, так и JSX-компоненты. Пример структуры файла Example.mdx:

# Заголовок документа

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

<MyComponent prop="value" />

В этом примере MyComponent — обычный React-компонент, который необходимо импортировать в MDX-файл:

import MyComponent from './MyComponent';

MDX автоматически компилирует Markdown и JSX в единый React-компонент.

Использование MDX в React-приложении

Импорт MDX-файлов в React выглядит следующим образом:

import Example from './Example.mdx';

function App() {
  return (
    <div>
      <Example />
    </div>
  );
}

export default App;

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

Передача пропсов в MDX

MDX позволяет передавать данные через пропсы. Например:

<Example someProp="Hello World" />

Внутри MDX-файла можно получить пропсы через объект props:

{props.someProp}

Это открывает возможности динамического контента, что особенно полезно для документации или блогов.

Кастомизация рендеринга элементов

MDX поддерживает переопределение стандартных Markdown-элементов с помощью компонента MDXProvider:

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

const components = {
  h1: CustomHeading,
};

function App() {
  return (
    <MDXProvider components={components}>
      <Example />
    </MDXProvider>
  );
}

В данном случае все заголовки <h1> в MDX-файлах будут рендериться через CustomHeading.

Динамическая загрузка MDX-файлов

Vite поддерживает динамический импорт MDX, что позволяет загружать контент по мере необходимости:

import React, { useState, useEffect } from 'react';

function DynamicMDX() {
  const [MDXContent, setMDXContent] = useState(null);

  useEffect(() => {
    import('./Example.mdx').then((module) => setMDXContent(() => module.default));
  }, []);

  if (!MDXContent) return <p>Загрузка...</p>;

  return <MDXContent />;
}

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

Поддержка TypeScript

MDX можно использовать вместе с TypeScript, создав типизацию для пропсов:

interface ExampleProps {
  someProp: string;
}

const Example: React.FC<ExampleProps> = ({ someProp }) => {
  return <div>{someProp}</div>;
};

export default Example;

Для MDX-файлов рекомендуется создать глобальную декларацию типов mdx.d.ts:

declare module '*.mdx' {
  let MDXComponent: (props: any) => JSX.Element;
  export default MDXComponent;
}

Это позволяет корректно импортировать MDX-файлы в TypeScript-проектах.

Работа с плагинами и расширениями MDX

MDX поддерживает плагины Remark и Rehype, которые позволяют изменять синтаксис Markdown, добавлять подсветку кода, таблицы стилей и другие возможности. Настройка плагинов выполняется через Vite:

import mdx from 'vite-plugin-mdx';
import remarkGfm from 'remark-gfm';
import rehypeHighlight from 'rehype-highlight';

export default {
  plugins: [
    mdx({
      remarkPlugins: [remarkGfm],
      rehypePlugins: [rehypeHighlight],
    }),
  ],
};

Это позволяет расширять функциональность MDX без изменения основного кода компонентов.

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

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

Совместимость с маршрутизацией

MDX хорошо интегрируется с React Router или Next.js, позволяя использовать файлы как страницы:

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

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}

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

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