Плагины для редакторов

MDX — это расширение Markdown, которое позволяет включать JSX-компоненты прямо в текст документа. Для эффективной работы с MDX важно понимать, как можно расширять функциональность редакторов с помощью плагинов. Плагины в контексте MDX работают как промежуточный слой между парсером Markdown и сборщиком JavaScript-кода, позволяя модифицировать AST (Abstract Syntax Tree), добавлять новые возможности синтаксиса и интегрировать сторонние библиотеки.


Типы плагинов

1. Remark-плагины

Remark — это система обработки Markdown на уровне AST. Она отвечает за разбор и преобразование исходного Markdown в дерево узлов.

  • Добавление синтаксиса: можно внедрять пользовательские ноды, например, для новых типов блоков или интерактивных элементов.
  • Форматирование текста: автоматическая обработка заголовков, списков, ссылок или исправление опечаток.
  • Валидация: проверка структуры документа, например, наличие обязательных заголовков или корректность ссылок.

Пример подключения Remark-плагина в MDX:

import { MDXProvider } from '@mdx-js/react';
import remarkSlug from 'remark-slug';
import remarkAutolinkHeadings from 'remark-autolink-headings';

const mdxOptions = {
  remarkPlugins: [remarkSlug, remarkAutolinkHeadings],
};

<MDXProvider components={{}}>
  <MDXRenderer options={mdxOptions}>{content}</MDXRenderer>
</MDXProvider>

Ключевые моменты:

  • remarkSlug автоматически добавляет id к заголовкам.
  • remarkAutolinkHeadings позволяет делать заголовки кликабельными.

2. Rehype-плагины

Rehype отвечает за обработку HTML после конвертации Markdown/MDX в HTML.

  • Стилизация: добавление классов и атрибутов к HTML-элементам.
  • Оптимизация HTML: минификация, удаление пустых узлов.
  • Интерактивные улучшения: добавление элементов для работы с динамическими компонентами React.

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

import rehypePrism from '@mapbox/rehype-prism';

const mdxOptions = {
  rehypePlugins: [rehypePrism],
};

Ключевой момент: rehypePrism позволяет делать подсветку синтаксиса для блоков кода.


Создание собственного плагина

Remark-плагин

Структура собственного плагина выглядит так:

function remarkMyPlugin() {
  return (tree) => {
    visit(tree, 'heading', (node) => {
      node.children.push({
        type: 'text',
        value: ' ?'
      });
    });
  };
}
  • visit — функция из пакета unist-util-visit для обхода дерева AST.
  • tree — объект AST документа.
  • В примере к каждому заголовку добавляется символ “?”.

Rehype-плагин

function rehypeAddTargetBlank() {
  return (tree) => {
    visit(tree, 'element', (node) => {
      if (node.tagName === 'a') {
        node.properties = node.properties || {};
        node.properties.target = '_blank';
        node.properties.rel = 'noopener noreferrer';
      }
    });
  };
}
  • Этот плагин делает все ссылки открывающимися в новом окне.
  • Можно комбинировать несколько таких плагинов, создавая сложные цепочки обработки.

Интеграция с редакторами

MDX-плагины тесно связаны с редакторами типа MDX Deck, Next.js, Gatsby, а также визуальными редакторами на базе Slate.js или ProseMirror. Основные принципы интеграции:

  • Передача плагинов через опции: remarkPlugins и rehypePlugins подключаются в конфигурацию парсера MDX.
  • Композиция: несколько плагинов можно объединять в массив, порядок важен — плагины применяются последовательно.
  • Совместимость: некоторые плагины требуют строгого соответствия версии MDX и React.

Пример конфигурации в Next.js:

import { serialize } from 'next-mdx-remote/serialize';
import remarkGfm from 'remark-gfm';
import rehypeHighlight from 'rehype-highlight';

export async function getStaticProps() {
  const mdxSource = await serialize(content, {
    mdxOptions: {
      remarkPlugins: [remarkGfm],
      rehypePlugins: [rehypeHighlight],
    },
  });

  return { props: { mdxSource } };
}

Лучшие практики

  • Минимизировать количество плагинов для повышения производительности.
  • Проверять совместимость с текущей версией MDX и React.
  • Использовать официальные плагины для популярных задач (подсветка кода, таблицы, автоссылки).
  • Комбинировать Remark и Rehype для разделения задач на работу с AST и работу с HTML.
  • Логировать изменения AST при разработке собственного плагина, чтобы отлавливать ошибки.

Заключение по архитектуре плагинов

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