Обратная совместимость

Библиотека Marked для JavaScript активно развивается, но при этом сохраняет механизмы обратной совместимости, что позволяет существующим проектам продолжать работать без существенных изменений при обновлении версии библиотеки. Разберём ключевые аспекты обратной совместимости в Marked.


Версионная политика и стабильные интерфейсы

Marked придерживается семантического версионирования (Semantic Versioning). Основные принципы:

  • MAJOR версия изменяется при несовместимых изменениях API.
  • MINOR версия добавляет функциональность без нарушения существующего API.
  • PATCH версия исправляет ошибки и баги, не влияя на текущий функционал.

Это позволяет разработчикам ориентироваться на стабильность методов и конфигураций, особенно при обновлении библиотеки.


Ключевые объекты и функции

Marked предоставляет следующие стабильные объекты и функции, которые сохраняются между минорными и патч-версиями:

  • marked.parse(markdownString, options) — основной метод для преобразования Markdown в HTML.
  • marked.Parser и marked.Lexer — классы для более детального контроля процесса парсинга.
  • marked.Renderer — объект для кастомизации HTML-вывода.

Использование этих интерфейсов гарантирует минимальный риск сломать существующий код при обновлении библиотеки.


Обновления синтаксиса Markdown

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

  • Улучшенная обработка GFM (GitHub Flavored Markdown): таблицы, списки задач, автолинк.
  • Расширенные возможности для inline HTML, с опцией отключения через options.sanitize.
  • Поддержка новых типов токенов, таких как footnotes или definition lists, при условии явного включения через настройки.

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


Опции конфигурации и их сохранение

Marked позволяет передавать объект конфигурации, который контролирует поведение парсера и рендерера:

const options = {
  gfm: true,
  breaks: false,
  sanitize: false,
  smartLists: true,
  smartypants: false
};
const html = marked.parse(markdownString, options);
  • Старые опции остаются функциональными в новых версиях.
  • Добавление новых опций не ломает старый код — если опция не передана, используется значение по умолчанию.
  • Удаление или переименование опции всегда сопровождается выпуском мажорной версии, что сигнализирует о возможной несовместимости.

Совместимость с Node.js и браузером

Marked поддерживает работу как в Node.js, так и в браузере. Для обратной совместимости:

  • Использование через require('marked') в Node.js продолжает работать во всех новых версиях.
  • Для браузерного использования сохраняется глобальная переменная window.marked при подключении через <script> тег.
  • Модули ES6 (import { marked } from 'marked') остаются полностью совместимыми с предыдущими версиями, если не изменена мажорная версия библиотеки.

Совместимость с кастомными рендерерами

Одним из ключевых аспектов обратной совместимости является поддержка кастомных рендереров:

const renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
  return `<a href="${href}" target="_blank">${text}</a>`;
};
marked.use({ renderer });
  • Любые методы кастомного рендерера, добавленные пользователем, продолжают работать в новых минорных и патч-версиях.
  • Добавление новых методов рендерера не ломает старый код: если метод не определён, используется стандартная реализация.

Обработка ошибок и предупреждений

Marked старается сохранять стабильность при изменениях:

  • Ошибки при парсинге Markdown не приводят к исключениям, а обрабатываются через токены lexer.tokens.
  • Старый код, который полагается на поведение по умолчанию, продолжает корректно работать без изменений.
  • Новые предупреждения добавляются как опциональные события, которые старые проекты могут игнорировать.

Советы по безопасному обновлению

Для минимизации рисков при обновлении Marked:

  1. Использовать фиксированные версии через package.json, чтобы исключить автоматические обновления мажорной версии.
  2. Проверять наличие новых опций и синтаксических расширений, которые могут повлиять на вывод.
  3. Тестировать критические блоки, использующие кастомные рендереры или парсеры, после обновления библиотеки.
  4. Использовать механизм marked.use() для подключения новых функций, не ломая существующие кастомизации.

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