Распространенные ошибки

Неправильная структура файлов MDX

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

Пример типичной ошибки:

# Заголовок

<MyComponent />

Если MyComponent не был импортирован:

import MyComponent from './MyComponent';

то приложение вызовет ошибку компиляции.

Рекомендация: всегда проверять импорты и наличие всех компонентов перед использованием в MDX.


Отсутствие корректного экспорта

MDX-файлы могут экспортировать компоненты и данные через export const. Часто возникает ошибка при попытке использовать переменные без экспорта:

export const title = "Статья о MDX";

# {title}  // Ошибка: переменная не определена в MDX-контексте

Правильный способ:

export const title = "Статья о MDX";

# {title}

При этом важно учитывать, что экспорты должны быть доступны в момент рендера.


Конфликты с именами компонентов

MDX обрабатывает JSX-компоненты напрямую, поэтому использование зарезервированных имен React или HTML-элементов в качестве названий своих компонентов приведет к неожиданным результатам. Например, создание компонента с именем div или span перезапишет стандартные HTML-теги.

Правило: компоненты должны иметь уникальные, начинающиеся с заглавной буквы имена.


Неправильное использование JSX внутри Markdown

MDX позволяет вставлять JSX-код прямо в Markdown, но некоторые синтаксические конструкции вызывают ошибки:

# Заголовок

<p>Параграф</p>
<MyComponent>
  <p>Вложенный параграф</p>
</MyComponent>

Внутри JSX все теги должны быть корректно закрыты. Например, <img> без закрывающего слеша вызовет ошибку в MDX:

<img src="image.png" />  // корректно
<img src="image.png">   // ошибка

Попытка использования динамического импорта без await

MDX поддерживает использование асинхронных компонентов, однако попытка загрузить их динамически без await приведет к undefined. Пример ошибки:

const DynamicComponent = import('./DynamicComponent');
<DynamicComponent />  // Ошибка: не React-компонент

Правильный способ:

import dynamic from 'next/dynamic';
const DynamicComponent = dynamic(() => import('./DynamicComponent'));

<DynamicComponent />

Игнорирование контекста MDXProvider

MDXProvider позволяет глобально переопределять стандартные элементы Markdown, такие как h1, p, a. Часто разработчики используют собственные компоненты без подключения MDXProvider, что приводит к потере единообразного стиля.

Пример ошибки:

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

<MDXProvider components={{ p: MyParagraph }}>
  <Content />  // Content — MDX-файл
</MDXProvider>

Если забыть обернуть <Content /> в MDXProvider, p останется стандартным HTML-тегом.


Проблемы с синтаксисом Markdown

MDX строго следует правилам Markdown, поэтому распространены ошибки с вложенными списками, таблицами и цитатами:

- Пункт 1
  - Подпункт 1
- Пункт 2

Если отступы нарушены, Markdown-парсер может неправильно отобразить список. Аналогично, таблицы требуют строгого выравнивания | и -.


Ошибки при использовании пропсов

MDX позволяет передавать пропсы в компоненты, но синтаксис должен быть корректным:

<MyComponent text="Привет" count={5} />  // корректно
<MyComponent text='Привет' count="5" />  // count передан как строка, а не число

Многие ошибки возникают именно из-за несоответствия типов пропсов.


Игнорирование оптимизации рендеринга

MDX может создавать большие документы с множеством компонентов. Неправильная организация компонентов ведет к повторным рендерам и замедлению приложения. Необходимо избегать:

  • Массивного импорта больших библиотек внутри MDX.
  • Создания новых функций внутри JSX без мемоизации.
  • Частого пересоздания компонентов без React.memo.

Несовместимость версий

MDX активно развивается, и часто встречаются ошибки при использовании разных версий @mdx-js/react, @mdx-js/loader и React. Например, MDX v2 использует другой API импорта и требует:

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

вместо устаревших импортов из v1. Игнорирование этого вызывает ошибки компиляции или некорректный рендер.


Проблемы с TypeScript

При использовании TypeScript с MDX важно правильно типизировать компоненты:

import { FC } from 'react';

interface Props {
  title: string;
}

const MyComponent: FC<Props> = ({ title }) => <h1>{title}</h1>;

Ошибка часто возникает при импорте MDX-файла без объявления типа:

import Content from './Content.mdx'; // Ошибка TS

Необходимо добавить декларацию модуля:

declare module '*.mdx' {
  let MDXComponent: FC;
  export default MDXComponent;
}

Эти ошибки являются самыми распространенными при работе с MDX и их своевременное понимание позволяет избежать множества проблем при интеграции Markdown и React в одном проекте.