Как проходит сборка
Сборка превращает Recipe и снимок данных в Document, а Document — в HTML. Эта глава описывает путь страницы и гарантии, которые даёт сборка.
Путь страницы
Сборка всегда идёт одним путём:
Recipe + снимок настроек и содержимого
↓ SF.Composition.resolveRecipe()
Document + перечень зависимостей
↓ SF.Composition.render()
HTML + ресурсы + сведения для оживления
- Раскрытие Recipe. Framework читает Recipe, получает от продукта разрешённые настройки и содержимое, раскрывает только выбранные шаблоны и варианты.
- Проверка и нормализация. Полученное дерево проверяется как Document, приводится к канонической форме и получает отпечаток.
- Отрисовка. Рендерер — функция типа, создающая разметку, — превращает Document в HTML и перечисляет нужные ресурсы.
Всё или ничего
Ошибка на любом шаге останавливает сборку целиком. Тогда
document имеет значение null, перечень зависимостей тоже null, а диагностика указывает
причину; частичного Document не бывает, и опубликовать его нельзя. Отказ в доступе к тексту, несовпадение ревизии
шаблона, цикл ссылок, превышение лимита — всё это ошибки, а не «пустые места».
Этот порядок одинаков для предварительного просмотра, публикации и пересборки после изменения шаблона или содержимого: всегда известно, какие данные участвовали в результате, и неполная страница не активируется.
Рендерер не ходит за данными
После получения Document рендерер не выбирает варианты заново и не запрашивает данные. Всё, что нужно для вывода, уже лежит в документе. Именно это делает результат воспроизводимым: один Document даёт один HTML на сервере и в браузере.
Когда Recipe создаёт продукт
Продукт может сам строить Recipe. Например, генератор статического сайта читает Markdown и унаследованные настройки сайта, раздела и страницы, создаёт Recipe и передаёт его общему сборщику Framework. Рендереры продукта превращают полученный Document в статический HTML.
Markdown + настройки сайта
↓ адаптер продукта
Recipe
↓ resolveRecipe()
Document
↓ рендереры продукта
статический HTML
Чтение исходников и наследование настроек остаются задачей продукта. Общий стандарт отвечает за проверяемую сборку дерева. Отчёт страницы содержит отпечатки Recipe и Document, поэтому всегда видно, из каких входов получен результат.
Серверному продукту для этого не нужен исходный репозиторий Framework: модуль
композиции поставляется в готовой поставке ui как ESM-модули рядом с Core
(distr/core/js/composition/). В браузере он доступен как SF.Composition
сразу после выполнения Core (core.min.js или читаемого core.js), без
ожидания событий Loader (см. События загрузчика).
На сервере или в сборке на Node.js модуль импортируется из поставки. Модуль
index.mjs экспортирует под теми же именами всё, что есть в SF.Composition
(resolveRecipe, validate, normalize, render, extendRegistry,
createRegistry, BUILTIN_TYPE_MANIFESTS, compositionTypeFromSmartManifest
и остальные), а экспорт по умолчанию — сам объект Composition:
import { readFile } from 'node:fs/promises';
import { render, extendRegistry, compositionTypeFromSmartManifest } from './ui/distr/core/js/composition/index.mjs';
// Тип для Smart-компонента берётся из его манифеста в той же поставке.
const buttons = JSON.parse(await readFile('./ui/distr/smart/buttons/smart.manifest.json', 'utf8'));
const doc = JSON.parse(documentJson); // документ simai.composition.document
const result = await render(doc, { registry: extendRegistry([compositionTypeFromSmartManifest(buttons)]) });
Если в документе есть Smart-узел, страница с результатом подключает Core и Loader: узел выводится тегом компонента, а загружает его Loader (см. Smart-компонент в макете).
Модулю не нужны браузерные объекты вроде window и document: из
глобальных объектов он берёт только crypto.subtle, TextEncoder и URL,
которые есть в Node.js 20 и новее. Гейт Framework работает на Node.js 20.
В браузере crypto.subtle есть только в защищённом контексте (https или
localhost); без него render() выбрасывает ошибку
composition_crypto_unavailable.
Смотрите также
- Шаблоны, вставки и варианты — шаблоны, вставки и варианты Recipe.
- Содержимое и данные — входы, снимок и перечень зависимостей.
- API сборки и отрисовки — операции, их аргументы и результаты.