---
metadata:
  - name: generator
    content: Diplodoc Platform v5.52.0
alternate:
  - https://3y3.dev/en/tools/docs/build.md
  - https://3y3.dev/ru/tools/docs/build.md
  - href: ru/tools/docs/build.md
    type: text/markdown
    title: Markdown version
  - href: ../../llms.txt
    type: text/markdown
    title: llms.txt
updatedAt: '2026-07-18T17:24:13.000Z'
---
> **Documentation Index:** Fetch the complete configuration index at https://3y3.dev/ru/llms.txt

# Сборка документации

Cборка проекта выполняется командой `yfm build` с параметрами:

* `--input, -i` — путь до директории проекта (по умолчанию — текущая папка);
* `--output, -o` — путь до директории для выходных данных (обязательный параметр).

```shell script
# полная команда
yfm build -i ./input-folder -o ./output-folder

# также, доступна сокращенная форма без build
yfm -o ./output-folder
```

Стандартным выходным форматом сборщика является HTML.

Полный список параметров сборки можно [найти в статье](https://3y3.dev/ru/tools/docs/settings.md) или вывести в консоли командой `yfm build --help`.

## YFM → YFM {#yfm}

Вы можете выполнить промежуточную сборку YFM в YFM. Для этого при выполнении команды укажите ключ запуска `--output-format=md`.

При сборке в YFM выполняются:
* [вставки](https://3y3.dev/ru/project/toc-includes.md) и [проверки условия видимости разделов](https://3y3.dev/ru/project/toc.md#when) в файлах оглавлений;
* [проверки условия отображения контента](https://3y3.dev/ru/syntax/vars.md#conditions) на страницах документа;
* [подстановки переменных](https://3y3.dev/ru/syntax/vars.md#subtitudes), если указан параметр `apply-presets`;
* [инлайнинг SVG-изображений](https://3y3.dev/ru/syntax/media.md#img-inline);
* [подстановки заголовков статей вместо {#T}](https://3y3.dev/ru/syntax/links.md#autotitle);
* [вставки контента из файлов](https://3y3.dev/ru/syntax/includes.md).

Используйте этот вид сборки, чтобы поддерживать несколько вариантов документации для разных пользователей. Если в документации есть разделы с внутренней информацией, вы можете держать два репозитория — приватный и публичный, и синхронизировать приватный в публичный с помощью условий.

## Watch-режим {#watch}

Вы можете автоматизировать пересборку отдельных статей при их изменении. Для этого вызовите `yfm build` с параметром `--watch`: после сборки проекта программа перейдёт в режим инкрементальной пересборки и будет создавать или обновлять статьи после сохранения изменений в исходных файлах документации.

Для удобства, после пересборки открытого в браузере файла выполняется автоматическая перезагрузка страницы.

## Статистика сборки {#build-stats}

При запуске с ключом [`--build-stats`](https://3y3.dev/ru/tools/docs/settings.md#build-stats-flag) (или `buildStats: true` в [файле конфигурации](https://3y3.dev/ru/settings.md)) рядом с output записывается файл `yfm-build-stats.json` с метриками текущей сборки. Файл предназначен для CI-дашбордов, отслеживания регрессий и диагностики — для рантайма он не нужен.

По умолчанию включено для сборок `--output-format=md`, для остальных форматов — выключено. Чтобы отключить, передайте `--no-build-stats` или укажите `buildStats: false` в файле конфигурации.

Что попадает в файл:

* `cli` — версия пакета, версия Node, платформа, архитектура, релиз ОС.
* `build` — `startedAt`, `finishedAt`, `durationMs`, грубое разбиение по фазам `phasesMs.{prepare, entries, finalize}` (на основе времени `Entry`-хука), `outputFormat`, `langs`, `inputDir`, `outputDir`, `features` (включённые булевы флаги), `memoryUsageMb` (`heapUsed` в момент завершения, в МБ), `worker.maxOldSpace`.
* `counters` — `tocs`, `entriesPlanned` / `entriesProcessed`, разбивки `entriesByExtension` и `entriesByLang`, `headings` и `contentBytes` (для md-страниц), `graph.{entries, sources, resources, missed, edges}` — снимок графа зависимостей (страницы, включаемые файлы, ассеты, отсутствующие пути, число рёбер), а также `warnings` / `errors` (общее число) и `warningsByCode` / `errorsByCode` — разбивка по кодам ошибок (`YFM013`, `YFM016` и т.п.; сообщения без распознанного кода попадают в бакет `(uncoded)`).
* `output` — `files`, `totalBytes`, `bytesByExtension`.
* `schemaVersion` — версия формата файла. При расширении формата схема будет совместимой; ломающие изменения увеличат это число.

Пример выходного файла:

```json
{
  "schemaVersion": 1,
  "cli": { "version": "5.29.0", "node": "v22.22.0", "platform": "darwin", "arch": "arm64" },
  "build": {
    "durationMs": 1474,
    "phasesMs": { "prepare": 1242, "entries": 148, "finalize": 84 },
    "outputFormat": "html",
    "langs": ["ru", "en"],
    "features": ["addAlternateMeta", "allowHtml", "buildStats", "sanitizeHtml"],
    "memoryUsageMb": 256
  },
  "counters": {
    "tocs": 3,
    "entriesPlanned": 133,
    "entriesProcessed": 133,
    "entriesByExtension": { ".md": 122, ".yaml": 11 },
    "entriesByLang": { "ru": 91, "en": 42 },
    "headings": 345,
    "contentBytes": 1693771,
    "graph": { "entries": 130, "sources": 12, "resources": 74, "missed": 0, "edges": 129 },
    "warnings": 3,
    "errors": 1,
    "warningsByCode": { "YFM013": 2, "(uncoded)": 1 },
    "errorsByCode": { "YFM016": 1 }
  },
  "output": {
    "files": 421,
    "totalBytes": 45350699,
    "bytesByExtension": { ".html": 2865454, ".js": 9721257, ".png": 24588860 }
  }
}
```

## Карта содержимого сборки {#build-content}

При запуске с ключом [`--build-content`](https://3y3.dev/ru/tools/docs/settings.md#build-content-flag) (или `buildContent: true` в [файле конфигурации](https://3y3.dev/ru/settings.md)) рядом с output записывается файл `yfm-build-content.json` с отпечатком содержимого каждой страницы и ассета. Файл предназначен для внешних инструментов, которые сравнивают две сборки и точно определяют список изменившихся страниц — переиндексация поиска, уведомления об изменениях и т.п. Для рантайма он не нужен.

По умолчанию включено для сборок `--output-format=md`, для остальных форматов — выключено. Чтобы отключить, передайте `--no-build-content` или укажите `buildContent: false` в файле конфигурации.

Сама сборка не знает ни о каких других ревизиях и не выполняет инкрементальную сборку: diff вычисляется как пост-обработка двух файлов манифеста.

Что попадает в файл:

* `schemaVersion` — версия формата файла. При расширении формата схема будет совместимой; ломающие изменения увеличат это число.
* `contentHashes` — таблица, ключи которой — **исходные пути** (стабильны между сборками; output-пути могут меняться из-за `hashIncludes`). Для каждого файла: `hash` (sha256 от стабильного представления файла в output, с префиксом `sha256-`) и `size` (размер файла в output в байтах). Стабильное представление — это файл с вырезанными перед хешированием полями VCS (`updatedAt`, `contributors`, `author`) и CLI-полем `metadata.generator` из frontmatter `.md` и блока `meta:` в `.yaml`. Так хеш отражает то, что видят читатели, а не каждый коммит или релиз CLI. Бинарные ассеты хешируются как есть.
* `pageAssets` — для каждой страницы — отсортированный список её прямых зависимостей типа `resource` (картинки, видео, SVG и т.п.), приведённых к исходным путям. Нужен потому, что ссылки на ассеты не имеют фингерпринта в теле страницы: изменение `pic.png` не меняет хеш страницы, но меняет `contentHashes["pic.png"]`, и `pageAssets` позволяет потребителю связать одно с другим.

Как изменения во вставках попадают в diff:

* `mergeIncludes: true` — содержимое вставки встроено в страницу, его байты входят в хеш страницы. Файл вставки в output не пишется и в `contentHashes` отсутствует.
* `mergeIncludes: false`, `hashIncludes: true` (по умолчанию) — страница ссылается на вставку под подписанным именем `inc-{12hex}.md`. Изменение вставки меняет её хеш и переименовывает её, что меняет ссылку в странице, что меняет хеш страницы.

Алгоритм diff (на стороне потребителя):

```
changed_pages = {
  p ∈ entries(curr) |
       prev.contentHashes[p]?.hash ≠ curr.contentHashes[p]?.hash
    OR ∃ a ∈ curr.pageAssets[p]:
         prev.contentHashes[a]?.hash ≠ curr.contentHashes[a]?.hash
}

added_pages   = keys(curr.contentHashes) \ keys(prev.contentHashes)
removed_pages = keys(prev.contentHashes) \ keys(curr.contentHashes)
```

Пример выходного файла:

```json
{
  "schemaVersion": 1,
  "contentHashes": {
    "ru/foo.md": { "hash": "sha256-...", "size": 1234 },
    "ru/foo/inc.md": { "hash": "sha256-...", "size": 567 },
    "ru/img/pic.png": { "hash": "sha256-...", "size": 8901 }
  },
  "pageAssets": {
    "ru/foo.md": ["ru/img/pic.png"]
  }
}
```

### Известные ограничения

Случаи, когда ключи в `contentHashes` могут «дрожать» или быть шумными независимо от реального изменения содержимого. Они не мешают основным сценариям (переиндексация поиска, уведомления об изменениях), но о них стоит знать:

* `_bundle/*` — пайплайн `output-html` копирует JS/CSS-чанки CLI в `_bundle/`, и хеш, зашитый в имена этих файлов, сдвигается при каждом апгрейде `@diplodoc/cli`. Потребители, сравнивающие две сборки, должны отфильтровывать ключи, начинающиеся на `_bundle/`.
* `_search/*` — если включён локальный поиск, `LocalSearchProvider` пишет ресурсы по пути `_search/<lang>/{timeOrigin}-resources.js`, где `{timeOrigin}` — время старта сборки. Каждая сборка даёт новое имя файла и новый ключ. Стоит отфильтровывать `_search/` или принимать этот шум.
* `mergeSvg: true` (по умолчанию) — SVG, на который ссылаются как `![](logo.svg)`, инлайнится в тело страницы *и* остаётся отдельным файлом в output. Изменение SVG переключает сразу три сигнала: хеш страницы, хеш отдельного `.svg` и страницу через `pageAssets`. Чтобы избежать двойного счёта, используйте `![](logo.svg){inline=false}`.
