Сообщения и логирование

Уровни логирования Remark и Rehype используют систему сообщений (messages), которая позволяет отслеживать ошибки, предупреждения и информационные уведомления при обработке Markdown или HTML. Каждое сообщение содержит объект с ключевыми полями:

  • type — тип сообщения: error, warning, info.
  • reason — текстовое описание причины сообщения.
  • position — объект с координатами в исходном тексте, содержащий start и end позиции, включая line и column.
  • fatal — булевое значение, указывающее, является ли ошибка критической (true для прекращения обработки).
  • source — источник сообщения, например, имя плагина или обработчика.

Сообщения могут агрегироваться в массив file.messages после обработки AST (Abstract Syntax Tree). Это обеспечивает централизованное хранение всех уведомлений, что особенно важно для сложных цепочек плагинов.


Создание сообщений вручную Для добавления собственного сообщения можно использовать вспомогательную функцию file.message(reason, position, [source]):

import {unified} from 'unified';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';

const processor = unified()
  .use(remarkParse)
  .use(() => (tree, file) => {
    const node = tree.children[0];
    if (node.type !== 'paragraph') {
      file.message('Первый узел должен быть абзацем', node.position, 'custom-check');
    }
  })
  .use(remarkStringify);

processor.process('**Заголовок**').then(file => {
  console.log(file.messages);
});

В примере создаётся сообщение, если первый узел не является абзацем. file.messages возвращает массив объектов сообщений, которые можно фильтровать, форматировать или логировать.


Обработка ошибок и предупреждений Ошибки и предупреждения могут быть критическими или некритическими. Критическая ошибка (fatal: true) прерывает выполнение цепочки процессоров. Для контроля используется метод VFile#fail:

file.fail('Критическая ошибка', node.position);

В отличие от file.message, file.fail выбрасывает исключение и завершает обработку. Для некритических ситуаций используется file.warn:

file.warn('Предупреждение: структура может быть некорректной', node.position);

warn добавляет сообщение с типом warning, но не прерывает выполнение.


Форматирование и вывод сообщений Для визуализации сообщений удобно использовать метод VFile#message.toString():

file.messages.forEach(msg => {
  console.log(msg.toString());
});

Стандартный вывод включает позицию в тексте, источник и текст причины:

custom-check:1:1-1:14: Первый узел должен быть абзацем

Для интеграции с инструментами сборки (например, ESLint, Vite, Webpack) сообщения можно преобразовывать в формат JSON, что упрощает автоматическую обработку и отображение пользователю.


Логирование в Rehype Rehype использует ту же систему сообщений, но применительно к HTML. Каждый узел HAST (HTML AST) может содержать информацию о позиции в исходном документе. Плагин Rehype может создавать сообщения через file.message точно так же, как Remark:

import {unified} from 'unified';
import rehypeParse from 'rehype-parse';
import rehypeStringify from 'rehype-stringify';

const processor = unified()
  .use(rehypeParse, {fragment: true})
  .use(() => (tree, file) => {
    tree.children.forEach(node => {
      if (node.tagName === 'script') {
        file.warn('Скрипты могут быть небезопасны', node.position);
      }
    });
  })
  .use(rehypeStringify);

processor.process('<div></div><script>alert(1)</script>').then(file => {
  console.log(file.messages);
});

Таким образом, можно отслеживать потенциально опасные элементы и предупреждать об их наличии без остановки всей обработки документа.


Агрегация сообщений при использовании плагинов Когда цепочка обработки включает несколько плагинов, каждое сообщение автоматически добавляется в общий массив file.messages. Это позволяет централизованно анализировать все ошибки и предупреждения. Для упрощения логики часто создают утилиты, фильтрующие сообщения по типу или источнику:

const errors = file.messages.filter(m => m.type === 'error');
const warnings = file.messages.filter(m => m.type === 'warning');

Можно выводить только критические ошибки для сборки, а информационные сообщения использовать для отладки.


Расширенные возможности

  1. Многоуровневые позицииposition поддерживает вложенные объекты для более точного указания диапазона текста в узле AST.
  2. Подключаемые источникиsource позволяет точно указать, какой плагин или модуль сгенерировал сообщение, что важно при комплексной обработке.
  3. Фильтрация и сортировка — сообщения можно сортировать по линии, типу или источнику, облегчая анализ больших файлов.
  4. Совместимость с CI/CD — благодаря строгой структуре сообщений можно автоматически генерировать отчёты ошибок для сборки или линтинга документации.

Практическое использование

  • Проверка Markdown на корректность структуры перед генерацией HTML.
  • Предупреждения о небезопасных HTML-тегах.
  • Локализация ошибок с указанием точной позиции в исходном тексте.
  • Централизованное логирование для систем сборки и тестирования.

Эта система сообщений делает Remark и Rehype удобными для построения надежных инструментов обработки документов, обеспечивая детальное отслеживание ошибок и предупреждений на всех этапах обработки AST.