unist-builder — это утилита для создания деревьев
синтаксических узлов в формате unist, который лежит в
основе библиотек Remark и Rehype. Она
позволяет программно формировать узлы Markdown или HTML, упрощая
генерацию AST (Abstract Syntax Tree) и взаимодействие с плагинами
экосистемы.
Библиотека предоставляет функцию
u(type, props?, children?), где:
paragraph, heading, text,
element, root и др.);depth для заголовков, url для
ссылок, alt для изображений);Простая структура узла в unist выглядит так:
{
type: 'имя_узла',
data: { /* дополнительные свойства */ },
children: [ /* дочерние узлы */ ]
}
unist-builder автоматизирует создание этой
структуры.
npm install unist-builder
Или через Yarn:
yarn add unist-builder
import u from 'unist-builder';
const textNode = u('text', 'Привет, мир!');
console.log(textNode);
Результат:
{
"type": "text",
"value": "Привет, мир!"
}
const paragraph = u('paragraph', [u('text', 'Это параграф с текстом.')]);
Структура AST:
{
"type": "paragraph",
"children": [
{
"type": "text",
"value": "Это параграф с текстом."
}
]
}
Для заголовков можно передавать объект с пропсами:
const heading = u('heading', { depth: 2 }, [u('text', 'Подзаголовок')]);
Результат:
{
"type": "heading",
"depth": 2,
"children": [
{
"type": "text",
"value": "Подзаголовок"
}
]
}
unist-builder идеально подходит для построения сложных
иерархий:
const root = u('root', [
u('heading', { depth: 1 }, [u('text', 'Главная тема')]),
u('paragraph', [u('text', 'Вступительный абзац.')]),
u('list', { ordered: true }, [
u('listItem', [u('paragraph', [u('text', 'Первый элемент')])]),
u('listItem', [u('paragraph', [u('text', 'Второй элемент')])])
])
]);
Такой корневой узел root может быть сразу передан в
Remark или Rehype для дальнейшей
обработки или рендеринга.
После построения дерева его можно обработать плагинами Remark:
import { remark } from 'remark';
import remarkStringify from 'remark-stringify';
remark()
.use(remarkStringify)
.process(root)
.then(file => {
console.log(String(file));
});
Результат генерации Markdown:
# Главная тема
Вступительный абзац.
1. Первый элемент
2. Второй элемент
unist-builder совместим и с HTML-деревьями через Rehype.
Основное отличие — типы узлов:
element вместо paragraph или
heading;tagName, properties и
children.Пример HTML-дерева:
const htmlRoot = u('root', [
u('element', { tagName: 'h1' }, [u('text', 'Заголовок')]),
u('element', { tagName: 'p' }, [u('text', 'Абзац текста')])
]);
После обработки через Rehype с плагином rehype-stringify
получится:
<h1>Заголовок</h1>
<p>Абзац текста</p>
Для HTML-элементов properties позволяет задавать любые
атрибуты:
const link = u('element', {
tagName: 'a',
properties: { href: 'https://example.com', target: '_blank' }
}, [u('text', 'Ссылка')]);
AST:
{
"type": "element",
"tagName": "a",
"properties": { "href": "https://example.com", "target": "_blank" },
"children": [
{ "type": "text", "value": "Ссылка" }
]
}
u для единообразного создания
узлов, вместо ручного создания объектов.unist-util-visit
и unist-util-map для обхода и трансформации деревьев.unist-builder позволяет легко формировать и
модифицировать Markdown и HTML-деревья, что упрощает работу с
экосистемой Remark/Rehype. Использование единообразной функции
u делает код чистым, предсказуемым и полностью совместимым
с плагинами. Такой подход особенно полезен для генерации динамического
контента, автоматической сборки документации и кастомной обработки
AST.