VFile — это концепция виртуального файла, используемая в экосистеме Remark и Rehype для представления содержимого текста вместе с метаданными и информацией об ошибках. VFile не обязательно соответствует физическому файлу на диске; это удобная структура для обработки Markdown, HTML и других текстовых форматов в памяти.
Объект VFile представляет собой JavaScript-объект с ключевыми свойствами:
value — основной текст содержимого.
Может быть строкой или Buffer.path — полный путь к исходному файлу.
Полезно для диагностики и генерации сообщений об ошибках.basename — имя файла без пути.stem — имя файла без расширения.extname — расширение файла (например,
.md или .html).dirname — путь к директории
файла.history — массив, содержащий все пути
файла в ходе обработки.data — произвольные метаданные,
которые можно использовать для хранения промежуточной информации в
процессе обработки.messages — массив объектов с
информацией об ошибках и предупреждениях, поддерживает стандарт VFile
Message.Пример создания VFile:
import {VFile} from 'vfile';
const file = new VFile({
path: 'docs/example.md',
value: '# Заголовок\n\nТекст документа'
});
console.log(file.basename); // "example.md"
console.log(file.stem); // "example"
console.log(file.extname); // ".md"
1. .toString([encoding]) Возвращает
содержимое файла в виде строки или Buffer. По умолчанию используется
UTF-8.
const content = file.toString();
2.
.message(reason, [position], [origin]) Создает
сообщение об ошибке или предупреждении. reason — текст
сообщения, position — местоположение в файле,
origin — идентификатор источника ошибки.
file.message('Некорректный заголовок', {line: 2, column: 1}, 'remark-lint');
console.log(file.messages);
3. .fail(reason, [position], [origin])
Создает критическую ошибку и выбрасывает исключение. Используется для
остановки обработки при серьезных нарушениях.
file.fail('Невозможно обработать файл', {line: 1});
4. .info(reason, [position], [origin])
Добавляет информационное сообщение, которое не считается ошибкой.
file.info('Файл прошел проверку стиля');
Remark использует VFile для передачи Markdown-документов между плагинами. Пример интеграции:
import {remark} from 'remark';
import remarkParse from 'remark-parse';
import {VFile} from 'vfile';
const markdown = new VFile({value: '# Заголовок\nТекст'});
remark()
.use(remarkParse)
.process(markdown)
.then((file) => {
console.log(String(file));
console.log(file.messages);
});
Ключевой момент — все плагины Remark получают один и тот же объект VFile, что позволяет хранить промежуточные данные и ошибки централизованно.
Rehype работает с HTML-подобными AST, но концепция VFile идентична:
import {rehype} from 'rehype';
import rehypeParse from 'rehype-parse';
import {VFile} from 'vfile';
const html = new VFile({value: '<h1>Заголовок</h1><p>Текст</p>'});
rehype()
.use(rehypeParse, {fragment: true})
.process(html)
.then((file) => {
console.log(file.value);
console.log(file.messages);
});
VFile здесь играет роль контейнера, который позволяет отслеживать исходное содержимое и сообщения об ошибках на всех этапах обработки AST.
file.data — это объект, в котором можно хранить любую
информацию для последующих этапов обработки. Например, подсчет
количества заголовков или сохранение ссылок:
file.data.headings = [];
file.data.links = [];
file.data.headings.push({text: 'Заголовок', level: 1});
file.data.links.push({url: 'https://example.com', text: 'Пример'});
Данные в file.data могут использоваться как плагинами
Remark/Rehype, так и сторонними утилитами, что делает VFile удобной
промежуточной структурой.
history.file.data, чтобы
избежать глобальных переменных.file.message, file.info и
file.fail для точного контроля над диагностикой.file.history.VFile — это ядро системы обработки текста в Remark и Rehype, обеспечивающее единообразие, прозрачность и контроль на каждом этапе анализа и трансформации документов.