В работе с Remark и Rehype часто возникает необходимость обрабатывать не только содержимое Markdown или HTML, но и сопутствующие метаданные, например, фронтматтер YAML или JSON-объекты, встроенные в документы. Корректная валидация этих данных обеспечивает надежность и предсказуемость последующей обработки.
Метаданные чаще всего хранятся в следующих форматах:
---\nkey: value\n---)Remark и Rehype позволяют получать эти данные через плагины и AST-узлы:
import { remark } from 'remark';
import frontmatter from 'remark-frontmatter';
const processor = remark()
.use(frontmatter, ['yaml']);
const file = await processor.process(`---
title: "Пример документа"
date: 2026-03-22
---`);
Фронтматтер YAML будет представлен как узел yaml в
дереве MDAST, и его содержимое можно разобрать с помощью
js-yaml.
Существует несколько способов проверять корректность метаданных:
import yaml from 'js-yaml';
const data = yaml.load(file.contents);
if (typeof data.title !== 'string') {
throw new Error('Поле title должно быть строкой');
}
if (!data.date) {
throw new Error('Отсутствует обязательное поле date');
}
import { z } from 'zod';
const metadataSchema = z.object({
title: z.string(),
date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
tags: z.array(z.string()).optional(),
});
const parsedData = metadataSchema.parse(data);
Использование таких библиотек позволяет сразу получать подробные ошибки и избегать ручных проверок.
Remark предоставляет механизм плагинов, который позволяет обрабатывать AST перед финальной генерацией документа. Валидация метаданных естественно встраивается в этот процесс.
Пример плагина для проверки фронтматтера:
function validateFrontmatter() {
return (tree, file) => {
const yamlNode = tree.children.find(node => node.type === 'yaml');
if (!yamlNode) return;
const data = yaml.load(yamlNode.value);
try {
metadataSchema.parse(data);
} catch (err) {
file.fail(`Ошибка валидации фронтматтера: ${err.message}`);
}
};
}
remark()
.use(frontmatter, ['yaml'])
.use(validateFrontmatter)
.process(markdownContent);
Плагин анализирует узел yaml, применяет схему и
генерирует ошибки через объект file, что интегрируется с
системой обработки ошибок Remark.
В Rehype метаданные чаще встречаются в атрибутах HTML или в скриптах JSON. Валидация осуществляется аналогично:
element и атрибут
data-*.Zod, Yup или
ручной проверки.Пример:
import { rehype } from 'rehype';
import rehypeParse from 'rehype-parse';
function validateDataAttributes() {
return (tree) => {
const elements = tree.children.filter(node => node.type === 'element');
elements.forEach(el => {
if (el.properties?.['data-meta']) {
const meta = JSON.parse(el.properties['data-meta']);
metadataSchema.parse(meta);
}
});
};
}
rehype()
.use(rehypeParse, { fragment: true })
.use(validateDataAttributes)
.process(htmlContent);
file в Remark и кастомные исключения в Rehype позволяют
легко отлаживать большие проекты.Метаданные могут включать вложенные объекты, массивы и условные поля. В таких случаях Zod и Yup позволяют строить рекурсивные схемы:
const complexSchema = z.object({
title: z.string(),
authors: z.array(z.object({
name: z.string(),
email: z.string().email().optional(),
})),
date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
});
Это обеспечивает строгую проверку структуры без необходимости писать десятки условных операторов вручную.
Метаданные становятся надежной частью конвейера обработки документов благодаря строгой валидации, интегрированной с AST-плагинами Remark и Rehype.