Для работы с Remark и Rehype требуется
установить соответствующие пакеты через npm:
npm install remark remark-html rehype rehype-stringify
remark — парсер и обработчик Markdown.remark-html — плагин для преобразования Markdown в
HTML.rehype — процессор для работы с HTML-деревьями.rehype-stringify — сериализатор HTML в строку.Pipeline обработки данных строится вокруг концепции последовательного применения плагинов, которые модифицируют дерево документа (AST — Abstract Syntax Tree). Основная структура выглядит так:
import { remark } from 'remark';
import remarkHtml from 'remark-html';
const markdown = `
# Заголовок первого уровня
Текстовый абзац с **жирным текстом**.
`;
const processed = await remark()
.use(remarkHtml)
.process(markdown);
console.log(String(processed));
remark() создаёт процессор Markdown..use() подключает плагин, в данном случае
remark-html, который преобразует AST Markdown в HTML..process() выполняет все подключённые плагины над
исходной строкой Markdown.processed — объект типа
VFile, который хранит результат обработки и метаданные. Для
получения строки используется String(processed).Rehype обрабатывает уже HTML-деревья. Он удобен для
дальнейшей трансформации HTML после конвертации из Markdown:
import { rehype } from 'rehype';
import rehypeStringify from 'rehype-stringify';
import rehypeParse from 'rehype-parse';
const html = `Заголовок
Параграф текста
`;
const processedHtml = await rehype()
.data('settings', { fragment: true })
.use(rehypeParse, { fragment: true })
.use(rehypeStringify)
.process(html);
console.log(String(processedHtml));
rehypeParse разбивает HTML на AST.rehypeStringify собирает AST обратно в строку.fragment: true указывает, что обрабатывается
фрагмент HTML, а не полный документ с и
.Для создания мощного pipeline Markdown → HTML → модификации можно объединять Remark и Rehype:
import { remark } from 'remark';
import remarkHtml from 'remark-html';
import { rehype } from 'rehype';
import rehypeHighlight from 'rehype-highlight';
import rehypeStringify from 'rehype-stringify';
const markdown = `
\`\`\`js
console.log('Hello, world!');
\`\`\`
`;
const html = await remark()
.use(remarkHtml)
.process(markdown);
const highlightedHtml = await rehype()
.data('settings', { fragment: true })
.use(rehypeHighlight)
.use(rehypeStringify)
.process(html);
console.log(String(highlightedHtml));
rehype-highlight добавляет подсветку синтаксиса для
кода..data('settings', { fragment: true })
предотвращает добавление лишних тегов и
при обработке фрагмента.Remark и Rehype используют общую структуру AST, где
каждый узел имеет свойства type, children и
value. На этом строятся пользовательские плагины:
function remarkUppercase() {
return (tree) => {
visit(tree, 'text', (node) => {
node.value = node.value.toUpperCase();
});
};
}
import { visit } from 'unist-util-visit';
const result = await remark()
.use(remarkUppercase)
.use(remarkHtml)
.process('Привет, мир!');
console.log(String(result));
visit позволяет обходить все узлы AST и применять
изменения к узлам определённого типа.Remark и Rehype поддерживают асинхронные плагины, что удобно при работе с сетевыми запросами, чтением файлов или динамическими трансформациями:
function remarkFetchData() {
return async (tree) => {
const data = await fetchSomeData();
visit(tree, 'text', (node) => {
node.value += ` (${data})`;
});
};
}
Promise.Для крупного проекта рекомендуется:
.freeze() для кэширования неизменяемых
частей AST.VFile для хранения метаданных документа
(название файла, путь, дата изменения).remark-loader или
rehype-loader. /
.unified-engine для пакетной обработки с асинхронными
потоками.