Миграция с markdown-it

При переходе с библиотеки markdown-it на Marked важно учитывать различия в архитектуре, API и возможностях расширения. Marked предлагает более прямой и минималистичный подход к разбору Markdown, что делает его быстрым и лёгким, но накладывает особенности на миграцию существующего кода.


Установка и базовое использование

Для начала работы с Marked необходимо установить пакет через npm:

npm install marked

Импорт и базовое использование в Node.js выглядит следующим образом:

import { marked } from 'marked';

const markdownString = '# Заголовок\n\nТекст с **жирным** форматированием.';
const html = marked(markdownString);

console.log(html);

Отличие от markdown-it: в markdown-it создаётся объект парсера с конфигурацией (const md = require('markdown-it')()), тогда как Marked экспортирует готовую функцию marked(), которую можно напрямую использовать.


Конфигурация и опции

Marked поддерживает несколько ключевых опций для настройки поведения парсера:

marked.setOptions({
  renderer: new marked.Renderer(),
  gfm: true,
  breaks: false,
  sanitize: false,
  smartLists: true,
  smartypants: false
});
  • renderer – кастомный рендерер для изменения вывода HTML.
  • gfm – поддержка GitHub Flavored Markdown (GFM).
  • breaks – управление переносами строк.
  • sanitize – фильтрация HTML (deprecated, теперь рекомендуется использовать DOMPurify).
  • smartLists – улучшенные списки.
  • smartypants – замена стандартных символов на типографские (например, кавычки).

В markdown-it эти опции задаются через объект при инициализации. В Marked используется глобальная конфигурация через setOptions или передача опций в вызове функции:

marked(markdownString, { gfm: false });

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

Marked позволяет полностью контролировать HTML-вывод с помощью кастомного рендерера:

const renderer = new marked.Renderer();

renderer.heading = (text, level) => {
  return `${text}`;
};

renderer.link = (href, title, text) => {
  return `${text}`;
};

marked.setOptions({ renderer });

Особенности миграции: в markdown-it используется система “правил” (rules) для каждого токена, а в Marked используется объект Renderer с методами для каждого элемента Markdown. Это требует переписывания кастомных плагинов под методы рендерера.


Работа с токенами и лексическим разбором

Marked поддерживает раздельный процесс лексинга и парсинга, что полезно при сложной обработке Markdown:

const tokens = marked.lexer(markdownString);
const html = marked.parser(tokens);
  • lexer – преобразует Markdown в массив токенов.
  • parser – превращает токены в HTML.

В markdown-it аналогичные функции скрыты внутри объекта md и используются реже, поэтому при миграции необходимо адаптировать существующие обработки токенов под lexer + parser.


Поддержка плагинов и расширений

Marked не имеет нативной системы плагинов, как markdown-it. Все расширения делаются через:

  1. Кастомные рендереры.
  2. Модификацию токенов перед вызовом parser.
  3. Обёртки вокруг marked().

Пример расширения для поддержки пользовательских блоков:

const lexer = new marked.Lexer();
lexer.rules.customBlock = /^:::\s*(\w+)\s*\n([\s\S]+?)\n:::/;

marked.use({
  tokenizer(src) {
    const match = lexer.rules.customBlock.exec(src);
    if (match) {
      return {
        type: 'customBlock',
        lang: match[1],
        text: match[2],
        tokens: [],
      };
    }
  },
  renderer(token) {
    if (token.type === 'customBlock') {
      return `
${token.text}
`; } } });

Разница с markdown-it: markdown-it использует плагины через md.use(plugin) и имеет встроенные механизмы для добавления правил. В Marked приходится вручную управлять токенизацией и рендерингом.


Обработка безопасности и XSS

Marked больше не рекомендует использовать опцию sanitize. Для безопасного вывода HTML лучше интегрировать отдельные библиотеки, например:

import DOMPurify from 'dompurify';

const dirtyHtml = marked(markdownString);
const cleanHtml = DOMPurify.sanitize(dirtyHtml);

В markdown-it есть встроенный html режим и возможность подключить markdown-it-sanitizer. При миграции нужно адаптировать безопасный вывод через внешние инструменты.


Поддержка GitHub Flavored Markdown

Marked поддерживает GFM и таблицы:

marked.setOptions({ gfm: true, tables: true });

Особенности миграции:

  • Таблицы в markdown-it обрабатываются через плагин markdown-it-table.
  • В Marked поддержка встроена, но поведение некоторых мелких особенностей GFM (например, авто-ссылок) может отличаться.

Сравнение производительности

Marked позиционируется как более быстрый парсер по сравнению с markdown-it. Это связано с минимальной системой токенизации и отсутствием лишней абстракции. Для больших Markdown-документов это может давать значительное ускорение.


Резюме ключевых отличий при миграции

Особенность markdown-it Marked
Инициализация const md = require('markdown-it')() marked() или marked.setOptions()
Плагины md.use(plugin) через кастомные рендереры/токены
Токены md.parse() скрыто marked.lexer() + marked.parser()
Рендеринг Правила для токенов (rules) Методы объекта Renderer
Безопасность Опции html/sanitize DOMPurify или внешние библиотеки
GFM Плагины Встроено
Производительность Средняя Высокая