Remark и Rehype — это мощные экосистемы для обработки Markdown и HTML в JavaScript. Remark работает с Markdown как с AST (Abstract Syntax Tree), что позволяет модифицировать, анализировать и трансформировать содержимое. Rehype аналогично работает с HTML. Взаимодействие этих библиотек в pipeline позволяет строить сложные процессы обработки текстового контента с максимальной гибкостью.
Pipeline представляет собой последовательность шагов, каждый из которых выполняет определённую задачу над AST. Например, для Markdown это может быть: парсинг → трансформация → генерация HTML. Основные компоненты:
remark-parse,
rehype-parse) — преобразуют текст в AST.remark-stringify,
rehype-stringify) — преобразуют AST обратно в текстовый
формат.Pipeline строится методом use и поддерживает цепочку
плагинов:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkStringify from 'remark-stringify';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
const processor = unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeStringify);
Интеграционное тестирование pipeline отличается от юнит-тестов тем, что проверяется не отдельный плагин, а взаимодействие всех компонентов. Основная цель — убедиться, что входной Markdown корректно проходит все этапы преобразования и конечный HTML соответствует ожиданиям.
const markdownInput = `
# Заголовок
Текст с **жирным** и _курсивом_.
`;
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
const pipeline = unified()
.use(remarkParse)
.use(remarkRehype)
.use(rehypeStringify);
const htmlOutput = await pipeline.process(markdownInput);
console.assert(
htmlOutput.toString().includes('<strong>жирным</strong>'),
'Тег <strong> не найден в HTML'
);
console.assert(
htmlOutput.toString().includes('<em>курсивом</em>'),
'Тег <em> не найден в HTML'
);
import { describe, it, expect } from '@jest/globals';
describe('Pipeline Remark → Rehype', () => {
it('Преобразует Markdown в корректный HTML', async () => {
const html = await pipeline.process(markdownInput);
expect(html.toString()).toContain('<h1>Заголовок</h1>');
expect(html.toString()).toContain('<strong>жирным</strong>');
expect(html.toString()).toContain('<em>курсивом</em>');
});
});
Pipeline может содержать несколько плагинов для расширенной обработки:
Проверка интеграции с этими плагинами включает не только корректность синтаксиса, но и структуру HTML:
const complexMarkdown = `
# Введение
Текст с сноской[^1].
[^1]: Пояснение.
`;
const complexPipeline = unified()
.use(remarkParse)
.use(require('remark-footnotes'), { inlineNotes: true })
.use(remarkRehype)
.use(rehypeStringify);
const output = await complexPipeline.process(complexMarkdown);
expect(output.toString()).toContain('<sup');
expect(output.toString()).toContain('<a href="#fn1">');
try/catch в
pipeline, чтобы тесты выявляли не только неверный HTML, но и падения
процесса.unified().freeze() для кэширования
настроенной цепочки, если pipeline повторно используется.Remark преобразует Markdown → AST, а Rehype работает с HTML AST.
Соединение через remark-rehype позволяет интегрировать оба
мира:
unified()
.use(remarkParse)
.use(remarkRehype, { allowDangerousHtml: true })
.use(rehypeStringify, { allowDangerousHtml: true });
Это важно для интеграционных тестов, так как гарантирует, что все элементы Markdown корректно отражаются в HTML, включая нестандартные или “опасные” HTML-теги.
Интеграционное тестирование pipeline Remark → Rehype обеспечивает уверенность, что весь процесс преобразования работает как единое целое, от исходного Markdown до итогового HTML. Оно охватывает парсинг, трансформацию, плагины и компиляцию, выявляя проблемы взаимодействия между компонентами и гарантируя корректность конечного контента.