Breaking changes

MDX, как расширение синтаксиса Markdown с поддержкой JSX, активно развивается, что иногда приводит к breaking changes — изменениям, которые нарушают обратную совместимость. Понимание этих изменений критично для поддержания существующих проектов и корректного обновления зависимостей.

Синтаксис импорта

Ранее MDX разрешал использование импорта компонентов в теле документа с синтаксисом:

import { Button } from './Button'
<Button>Click me</Button>

В новых версиях было введено строгое правило: все импорты должны находиться исключительно в начале файла. Любой импорт после контента или JSX-компонентов вызывает ошибку компиляции.

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

# Заголовок
import { Alert } from './Alert'  // Ошибка в MDX 2+
<Alert>Warning!</Alert>

Правильная организация:

import { Alert } from './Alert'

# Заголовок
<Alert>Warning!</Alert>

Обновление способа экспорта компонентов

MDX версии 2 и выше изменяет поведение по умолчанию для экспорта компонентов. Ранее разрешался экспорт напрямую через export default, что автоматически превращало документ в React-компонент:

export default function Page() {
  return <h1>Hello World</h1>
}

Теперь MDX ожидает, что контент документа остаётся самодостаточным, а экспорт пользовательских компонентов следует выполнять через именованные экспорты. Нарушение этого правила может привести к конфликтам с сборщиками вроде Vite или Next.js.

Рекомендуемый подход:

export const PageTitle = () => <h1>Hello World</h1>

Изменения в обработке JSX

MDX 2 полностью отказался от некоторых старых синтаксических конструкций JSX:

  1. Автозакрывающие теги: теперь обязательны для элементов без детей.

    <Button />   // корректно
    <Button>    // ошибка
  2. Inline JSX внутри Markdown: более строгие правила парсинга. Ранее можно было вставлять JSX между текстовыми блоками без ограничения; теперь такой код необходимо оборачивать в {}:

Это текст с компонентом {<Button>Click</Button>} внутри строки.

Поддержка атрибутов

Ранее MDX позволял использовать атрибуты без кавычек для строковых значений:

<Button color=red>Click</Button>

Теперь строковые значения атрибутов обязаны быть в кавычках:

<Button color="red">Click</Button>

Работа с плагинами Remark и Rehype

MDX 2 внедрила строгую типизацию и структуру AST (Abstract Syntax Tree), что привело к изменениям в интеграции плагинов:

  • Плагины, использующие устаревшие поля в remark или rehype, могут ломаться.
  • Требуется обновление до совместимых версий с новой версией MDX.
  • Функция remarkPlugins теперь ожидает массив функций без undefined значений — пустые элементы вызывают ошибку сборки.
const mdxOptions = {
  remarkPlugins: [remarkSlug],  // корректно
  rehypePlugins: []              // корректно
}

Обработка frontmatter

MDX 2 изменяет формат и парсинг frontmatter:

  • Все YAML-данные теперь парсятся строго как объект.
  • Пустые строки или некорректная структура YAML вызывают исключение.
  • Для совместимости рекомендуется всегда использовать ключи в кавычках и избегать неоднозначных типов данных.
---
title: "Заголовок"
date: "2026-03-23"
draft: false
---

Влияние на сборщики и маршрутизацию

Breaking changes в MDX затрагивают работу с Next.js и Gatsby:

  • Next.js: необходимо использовать @next/mdx или next-mdx-remote обновленных версий.
  • Gatsby: старые плагины gatsby-plugin-mdx несовместимы с синтаксисом MDX 2+, требуется обновление конфигурации.
  • Любые кастомные компоненты в MDXProvider должны быть проверены на корректность именованных экспортов.

Итоговые рекомендации при обновлении

  • Перенос всех импортов в начало файла.
  • Приведение всех JSX-компонентов к современному синтаксису.
  • Обновление всех плагинов и сборщиков до совместимых версий.
  • Проверка frontmatter и атрибутов на строгую типизацию и кавычки.
  • Тестирование всех страниц MDX после миграции для выявления скрытых ошибок компиляции.

Breaking changes в MDX направлены на повышение стабильности и предсказуемости кода, но требуют внимательной проверки проектов при обновлении библиотеки.