Live код и песочницы

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

Основы live-кода

Для реализации live-кода в MDX применяется компонент LiveProvider из библиотеки @mdx-js/react или специализированные решения вроде react-live. Основная идея заключается в том, чтобы предоставить пользователю поле для редактирования кода и моментальный просмотр результата его выполнения.

Пример минимальной конфигурации:

import { LiveProvider, LiveEditor, LiveError, LivePreview } from 'react-live';
import * as React from 'react';

const code = `<button onCl ick={() => alert('Hello!')}>Click me</button>`;

<LiveProvider code={code} scope={{ React }}>
  <LiveEditor />
  <LiveError />
  <LivePreview />
</LiveProvider>

Разбор компонентов:

  • LiveProvider – оборачивает блок live-кода и передаёт ему исходный код (code) и контекст (scope) с необходимыми библиотеками.
  • LiveEditor – редактор кода с подсветкой синтаксиса, в котором можно изменять код.
  • LiveError – отображает ошибки, возникающие при выполнении кода.
  • LivePreview – визуальное отображение результата выполнения кода.

Передача зависимостей через scope

scope – объект, через который live-код получает доступ к библиотекам и компонентам. Без корректного объявления всех используемых переменных выполнение кода вызовет ошибку.

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

import { Button } from '@chakra-ui/react';
import * as React from 'react';

const code = `<Button colorScheme="teal">Click me</Button>`;

<LiveProvider code={code} scope={{ React, Button }}>
  <LiveEditor />
  <LiveError />
  <LivePreview />
</LiveProvider>

Это позволяет безопасно интегрировать сторонние компоненты и стилизованные элементы.

Настройка песочницы

Для создания полноценной песочницы можно использовать свойства noInline и transformCode:

  • noInline – если установлен, весь код выполняется как блок, а не как выражение. Полезно для компонентов, содержащих несколько строк или хуки.
  • transformCode – функция для трансформации кода перед выполнением, например, для добавления обёртки <React.Fragment>.

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

<LiveProvider
  code={`function Counter() {
    const [count, setCount] = React.useState(0);
    return <button onCl ick={() => setCount(count + 1)}>{count}</button>;
  }`}
  scope={{ React }}
  noInline
>
  <LiveEditor />
  <LiveError />
  <LivePreview />
</LiveProvider>

Поддержка TypeScript в live-коде

Для TypeScript можно настроить компиляцию через babel или использовать специализированные решения с react-live и @babel/preset-typescript. Важно указать трансформацию кода до выполнения:

import { transform } from '@babel/standalone';
import presetTypescript from '@babel/preset-typescript';

const code = `const message: string = "Hello TypeScript"; <div>{message}</div>`;
const transformedCode = transform(code, { presets: [presetTypescript, 'react'] }).code;

<LiveProvider code={transformedCode} scope={{ React }}>
  <LiveEditor />
  <LiveError />
  <LivePreview />
</LiveProvider>

Стилизация и расширенные возможности

Редактор и preview можно кастомизировать через CSS или свойства компонентов:

  • LiveEditor: font-size, theme, lineNumbers, padding.
  • LivePreview: контейнер с фиксированной шириной, отступами, скроллингом.
  • LiveError: выделение текста ошибки, подсветка строки.

Пример кастомного оформления:

<LiveProvider code={code} scope={{ React }}>
  <div style={{ border: '1px solid #ddd', padding: '16px', borderRadius: '8px' }}>
    <LiveEditor style={{ fontFamily: 'monospace', backgroundColor: '#f5f5f5' }} />
    <LiveError style={{ color: 'red', marginTop: '8px' }} />
    <LivePreview style={{ marginTop: '16px' }} />
  </div>
</LiveProvider>

Совмещение с документацией

MDX позволяет вставлять live-код рядом с текстом и Markdown-разметкой, создавая динамическую и интерактивную документацию. Это особенно полезно для демонстрации UI-компонентов и обучения новым API без необходимости запускать отдельное окружение.

Блок live-кода может быть частью любого MDX-документа, что делает его универсальным инструментом для учебников, руководств и песочниц для демонстрации фреймворков и библиотек.