Переход Astro 7 на написанный на Rust движок markdown Sätteri превратил плавное обновление в тройной кошмар для сайтов, полагающихся на математические формулы, якоря заголовков и пользовательские конфигурации. Встроенные формулы (inline) всё еще работают, но блоки отображаемых формул (display-math) отображаются как обычные текстовые фрагменты кода, ID заголовков исчезают, а любые дополнительные опции, которые вы добавляете в конфиг Astro, молча игнорируются. Разработчикам, переходящим с более ранних версий Astro, теперь приходится переписывать плагины, иначе они рискуют получить сломанные страницы.

Почему это важно

Новый движок запускает встроенный синтаксический анализатор (syntax highlighter) перед любыми пользовательскими плагинами и принимает только три поля конфигурации верхнего уровня. Такой подход вступает в конфликт с тем, как большинство проектов Astro добавляют функционал: через плагины remark (MDAST) и rehype (HAST), которые должны запускаться после подсветки синтаксиса, и через гибкий объект конфигурации, который передается непосредственно базовому парсеру markdown.

Последствия проявляются на любой странице, где математические формулы в стиле LaTeX смешиваются с обычным контентом. Встроенная математика ($a+b$) рендерится нормально, но блок отображаемой формулы ($$a+b$$) оборачивается в тег <pre>, отображая сырую разметку вместо отформатированного уравнения. Якоря заголовков, обеспечивающие работу ссылок в оглавлении или глубоких ссылок (deep-linking), исчезают, потому что плагин генерации ID запускается до встроенного обработчика ID, и плагину autolink просто не к чему прикрепиться. Разработчики, пытавшиеся настроить синтаксический анализатор Shiki с помощью объекта shikiConfig, обнаруживают, что эта настройка бесследно исчезла.

Технические решения

1. Рендерите математику перед подсветкой

Первопричина заключается в порядке операций: анализатор Sätteri первым захватывает текст, классифицируя блок математики как обычный код. Чтобы вернуть математику, перенесите обработку на уровень MDAST (абстрактное синтаксическое дерево, представляющее markdown до того, как он станет HTML). Замените любые математические плагины уровня HAST их эквивалентами уровня MDAST и запускайте их до этапа подсветки. На практике замените плагины remark-math версией, которая подключается к этапу парсинга markdown, а затем позвольте анализатору работать с уже преобразованными узлами математики.

2. Измените порядок плагинов ID заголовков

ID заголовков генерируются встроенным плагином, который теперь выполняется после пользовательских плагинов. Переместите пользовательские генераторы ID или slug в начало списка плагинов, чтобы они запускались первыми. Типичная последовательность, восстанавливающая работу ссылок-якорей, выглядит так:

  1. slug/ID plugin
  2. autolink plugin
  3. любые другие remark-плагины

Благодаря тому, что ID будут созданы на раннем этапе, плагин autolink сможет добавить необходимые элементы <a >, и оглавление будет указывать на правильные разделы.

3. Соблюдайте строгую схему конфигурации Sätteri

Sätteri распознает только три поля в конфигурации markdown для Astro. Всё остальное, например shikiConfig, молча отбрасывается. Чтобы сохранить кастомные темы или настройки анализатора, переместите эти параметры на соответствующий уровень в иерархии конфигурации Astro.

Краткое руководство по замене

Если вы переносите классический стек markdown в Astro, замените старые remark-плагины новыми флагами функций, которые понимает Sätteri:

  • remark-gfmfeatures.gfm
  • remark-frontmatterfeatures.frontmatter
  • remark-mathfeatures.math
  • remark-directivefeatures.directive
  • remark-smartypantsfeatures.smartPunctuation
  • remark-wiki-linkfeatures.wikilinks

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

Правила для корректной работы плагинов с Sätteri

  • Только один проход — плагины видят дерево только один раз; они не могут повторно обрабатывать узлы, созданные на более поздних этапах конвейера.
  • Фабрика состояний — создавайте новый объект состояния для каждой страницы, чтобы избежать утечки данных между страницами.
  • Неизменяемые узлы — возвращайте новый узел, если вам нужно внести изменения; мутация существующего узла может нарушить последующие этапы обработки.
  • Никаких корневых фрагментов — вставляйте соседние элементы (siblings) с помощью предоставленных помощников вставки (insertion helpers) вместо создания узла фрагмента верхнего уровня.

При адаптации существующего плагина не полагайтесь на пример вывода в README. Отрендерите HTML оригинального плагина, захватите эту разметку и используйте её в качестве эталона для вашей версии, совместимой с Sätteri.

Итог

Движок Sätteri в Astro 7 обеспечивает скорость, но требует изменения порядка в цепочке обработки Markdown: рендерите математические формулы на уровне MDAST, размещайте плагины для ID заголовков в начале и ограничивайте конфигурацию тремя допустимыми полями. Следуйте сопоставлению флагов функций, соблюдайте правила однопроходной обработки и неизменяемых узлов, и вы восстановите поддержку математики, якорей и кастомных тем, от которых зависит ваш сайт. Затраты потребуются на начальном этапе, но результатом станет более предсказуемый и быстрый конвейер обработки Markdown.