К содержанию

Навигация

Из чего состоит Framework

Framework складывается из исходников, готовых поставок, выпусков, пакетов компонентов продуктов, загрузчика и документации. Здесь — из чего состоит каждая часть и как они связаны.

Исходники и поставки

Framework разрабатывается в одном месте, а проектам отдаётся в виде готовых поставок.

Репозиторий Роль Правится вручную
simai/ui-source Исходники: Core, Loader, утилиты, компоненты, Smart-компоненты, порты хоста, их контракты и тесты Да — единственное место правки
simai/ui-builder Воспроизводимая сборка поставок и пакетов из исходников: инструмент sf-build (см. Сборка пакета: sf-build) Да
simai/ui Поставка Framework: ядро, Loader, утилиты, компоненты, Smart-компоненты, правила загрузки (каталог distr/) Нет, генерируется
@simai-studio/ui (npm) Тот же выпуск пакетом npm для подключения с CDN: ядро целиком, модули только в сжатой форме (см. Пакет npm) Нет, издаётся из ui
simai/ui-doc Публичная документация Да

Поставка ui содержит всё, что нужно странице. Core (distr/core) — стили ядра, токены, темы, Loader и общая основа Smart-компонентов (core/js/smart-base.js: одна на страницу, её используют все Smart-компоненты). Рядом лежат утилиты (distr/utility), компоненты (distr/component), правила загрузки (distr/rule) и Smart-компоненты (distr/smart). Smart-компоненты без Core не работают.

Поставка ui получается только сборкой из исходников. Её не правят руками: следующая сборка всё равно перезапишет правку.

Каждый выпуск ui издан и пакетом npm @simai-studio/ui; его версия получается из времени коммита выпуска, а выпуск определяет коммит (см. Пакет npm).

Smart-компоненты, которые нужны одному продукту, в эти репозитории не входят: продукт хранит и поставляет их сам (см. Пакеты компонентов продуктов).

Выпуск

Поставка ui издаётся выпусками. Выпуск — одна сборка поставки, которая проверена целиком: ядро, утилиты, компоненты и Smart-компоненты вместе. У каждого выпуска есть идентификатор вида ui-<ревизия>, где ревизия — первые 12 знаков коммита сборки в ui, и запись о выпуске contracts/releases/ui-<ревизия>.lock.json. Идентификатор выпуска — не тег git: в адресах и закреплении проекта используется полный коммит из записи о выпуске (см. Выпуск и запись о выпуске).

Проект закрепляет выпуск целиком. Ветка main и слово latest — не релиз: они меняются без предупреждения. Подробно о поставке, выпусках и обновлении — см. Что такое поставка, Версии: как закрепить выпуск и Как обновить проект.

Пакеты компонентов продуктов

Компонент живёт у своего владельца. Framework содержит универсальные компоненты — те, что подходят любому проекту. Smart-компоненты, которые нужны одному продукту, в том числе составные, хранит и поставляет этот продукт. Такой набор называется пакетом продукта. Действующий пакет продукта — larena: четыре элемента sf-table, sf-data-view, sf-property-view и sf-admin-menu (описаны в справочнике Smart-компонентов). Его исходник — папка components репозитория simai/larena-ui, открытая по лицензии Apache-2.0. Пакет соответствует стандарту simai.component-package (см. Пакет компонентов (simai.component-package)) и расширяет Framework только через объявленные точки расширения (см. Принципы, принцип 8). Действующее издание стандарта — 1.1.1; оно закрепляет схему манифеста 2.5.0. Издание 1.0.0 закрепляло схему 2.2.0 и осталось в истории; требования те же.

Как устроен пакет продукта:

  • Где лежит исходник. В папке UI-репозитория продукта: в корне репозитория или в любой вложенной папке. Папка устроена так же, как исходники Framework: src/smart/<папка>/ — по папке на компонент (точка входа index.js, правило загрузки rule.js, манифест smart.manifest.json, шаблоны и стили — как у компонентов Framework, см. Из чего состоит), tests/ — тесты пакета. Сборка берёт из папки пакета только src/, tests/ и docs/. Пакет с одним компонентом целиком:

    Code
    acme-ui/
      framework.lock.json              ревизия Framework, к которой привязан пакет
      sf-build.config.json             настройки сборки
      src/smart/acme-counter/
        index.js                       класс компонента
        rule.js                        правило загрузки
        smart.manifest.json            манифест
        js/templates/default.js        встроенный шаблон
        js/templates/default.css       стили шаблона
      tests/acme-counter.test.mjs      тесты пакета
    

    Что пишется в каждом файле — ниже на этой странице, в Устройство компонента и в Манифест.

  • Импорты и стили. Компонент импортирует Framework относительными путями, как компоненты самого Framework. Базовый класс — экспорт по умолчанию модуля smart-base, остальное — именованные экспорты:

    JavaScript
    import SfBaseElement from '../../core/js/smart-base';
    import {pageText} from '../../core/js/page-language';
    import {html} from 'lit';
    

    Запись import {SfBaseElement} from '../../core/js/smart-base' не работает: сборка проходит, но класс в модуле не определён, и элемент не регистрируется. Сборка кладёт пакет поверх исходников Framework, поэтому относительные пути разрешаются. Модули общей основы — lit с его директивами, smart-base, page-language, position, control-spacing — в сборку компонента не попадают: на странице компонент берёт их из общей основы Smart-компонентов (см. Общая основа Smart-компонентов). Остальные импорты сборка включает в файл компонента.

    Стили компонента лежат рядом с шаблоном (js/templates/default.css), шаблон импортирует их (import './default.css'), а правило объявляет css: true; сборка выдаёт их файлом <папка>/css/<папка>.css. Стили пишутся в каскадных слоях Framework, как у его Smart-компонентов: оформление — в @layer sf.components, состояния — в @layer sf.states (см. Каскадные слои).

  • К чему привязан. Файл framework.lock.json в корне папки пакета закрепляет точную ревизию исходников Framework. Компоненты пакета опираются на базовый класс, вспомогательные модули и рендереры полей именно этой ревизии. Файл пакета не может заменить файл Framework: пакет только добавляет к нему.

    JSON
    {
      "schema": "simai.framework.product-package-source-lock.v1",
      "package": "shop",
      "source": {
        "repository": "simai/ui-source",
        "revision": "3029d8abda3899f055d91e1599e1c19a969e4369"
      }
    }
    

    schema — точно эта строка; source.repository — всегда simai/ui-source; source.revision — полный коммит исходников, из которых собран выбранный выпуск Framework (поле build_inputs.source.commit записи о выпуске, см. Выпуск и запись о выпуске; в примере — ревизия выпуска ui-106d5901f8c3). package необязателен; если он есть, он совпадает с именем пакета в сборке. Других полей сборка не читает.

  • Правило компонента. Файл src/smart/<папка>/rule.js записывает ровно одно правило cl-<папка> простыми данными, без регулярных выражений, функций и поля package:

    JavaScript
    SF.RuleLoader['cl-catalog'] = {
      tags: ['shop-catalog'],
      type: 'smart',
      mode: 'smart',
      js: true,
      css: true,
      relation: [{name: 'cl-icons'}, {name: 'cl-pagination'}],
    };
    

    В relation перечисляют всё, что компонент рисует из Framework: Smart- компоненты (cl-icons для тега <sf-icon>) и обычные компоненты, классы которых стоят в его шаблоне (buttons для sf-button, icons для классов sf-icon). Имя каждого правила — поле name в distr/rule/rule.json выпуска. Без такой связи стили обычного компонента загружаются, только если он уже есть на странице: на пустой странице кнопки пакета остаются без оформления.

    Пропущенную связь находит сама сборка: sf-build package и sf-build verify package перечисляют в предупреждениях каждый элемент Framework, который компонент рисует без связи с его правилом (тег в шаблоне, элемент из createElement или SF.create, описание component: {type: …}), и называют связь, которую нужно добавить. Элемент, который компонент загружает сам через SF.Loader.ensureSmartElementLoaded, предупреждения не вызывает. Предупреждение сборку не останавливает.

    Из этих файлов сборка создаёт общий файл правил пакета (см. Пакеты компонентов).

  • Имена элементов. Новый элемент пакета получает префикс владельца, а не sf-: shop-catalog, а не sf-catalog. Loader загружает любой тег, который перечислен в правиле пакета; тег без префикса sf- может занять только правило пакета, поэтому имена Framework остаются за Framework. Компонент, перенесённый из Framework в пакет, сохраняет имя с sf- (см. Пакет компонентов (simai.component-package)): поэтому элементы пакета larena называются sf-table, sf-data-view, sf-property-view и sf-admin-menu. Папку компонента называют так же, как тег, с префиксом владельца (acme-counter): правило пакета называется по папке (cl-acme-counter) и тогда не совпадёт с правилом Framework.

  • Тесты. sf-build тесты пакета не запускает. Пакет прогоняет свои тесты и браузерные пробы на закреплённой ревизии и на своей сборке до её использования: дерево wave-1/overlay рабочего каталога сборки (его сохраняют параметры --workspace и --keep-workspace, см. Сборка пакета: sf-build) — это исходники Framework с наложенными src/, tests/ и docs/ пакета, и тесты пакета читают в нём те же пути, что и тесты Framework. Тесты пишутся, как тесты Framework, файлами tests/*.test.mjs для встроенного средства запуска Node.js. В wave-1/overlay каталог tests/ содержит и тесты Framework, поэтому файлы пакета передают явно, по их общему началу имени: node --test tests/acme-*.test.mjs. Манифесты пакета проверяет node scripts/sf-contract.mjs build в том же дереве: код 0 означает, что все манифесты соответствуют схеме. Зависимости в wave-1/overlay уже установлены сборкой: тесты и sf-contract запускаются там без установки. Самый короткий тест пакета проверяет его манифест:

    JavaScript
    // tests/acme-counter.test.mjs
    import test from 'node:test';
    import assert from 'node:assert/strict';
    import {readFileSync} from 'node:fs';
    
    test('acme-counter declares its tag', () => {
      const manifest = JSON.parse(readFileSync('src/smart/acme-counter/smart.manifest.json', 'utf8'));
      assert.equal(manifest.custom_element, 'acme-counter');
    });
    
  • Как собирается. Инструмент сборки Framework sf-build (репозиторий ui-builder, см. Сборка пакета: sf-build) накладывает папку пакета на закреплённую ревизию исходников и собирает пакет дважды; обе сборки обязаны совпасть побайтно. Результат — каталог smart/: по каталогу на компонент (<папка>/js/<папка>.js и, если у компонента есть стили, <папка>/css/<папка>.css, а рядом сжатые .min.js и .min.css, которые Loader берёт по умолчанию) и файл правил пакета rule.js. Собранные файлы получаются только сборкой и вручную не правятся.

  • Как поставляется. Продукт кладёт собранный каталог smart/ в свою поставку и отдаёт его вместе с тем выпуском Framework, на котором пакет собран. Отдельного репозитория со сборками нет, и собранные файлы в git не хранятся: сборку пакета larena приносит поставка Larena или выпуск репозитория simai/larena-ui, а какой выпуск Framework ей нужен, называет её квитанция (см. «Пакет larena для проекта без Larena»). На странице пакет подключается как пакет компонентов Loader под именем продукта: SF_BOOT_CONFIG.packages.<имя> = {base: '<путь>/smart'}. Файл правил <base>/rule.js Loader загружает сам (см. Пакеты компонентов). Путь base страница получает от развёртывания: сценарий выкладки кладёт каталог smart/ под путём с ревизией пакета из квитанции (package_source.revision) и записывает этот путь в настройку страницы или в шаблон, который выводит SF_BOOT_CONFIG, — так путь и квитанция меняются вместе.

  • Квитанция пакета. Каждая сборка пакета сопровождается квитанцией, по которой проект закрепляет пакет (описание квитанции — ниже).

  • Лицензия. Компоненты пакета распространяются по лицензии продукта. Framework (ui) распространяется по лицензии Apache 2.0 (см. Принципы).

Квитанция пакета — файл package-receipt.json. Имя формата simai.framework.product-package-receipt записано в поле schema_id (не schema), старшая версия — в поле schema_version. Она записывает, что собрано, поверх чего, чем и с каким результатом:

Поле Что записано
package Имя пакета
loader Как объявить пакет на странице: SF_BOOT_CONFIG.packages.<имя>.base, каталог smart, файл правил smart/rule.js
package_source Репозиторий, ревизия и путь папки пакета, git-дерево этой папки
framework Ревизия исходников Framework и выпуск ui-<ревизия>, собранный из неё (null, если такого выпуска нет)
builder Ревизия сборщика и признак чистого рабочего дерева
node Версия Node.js, на которой шла сборка
output Число файлов, контрольная сумма списка всех файлов (manifest_sha256), имя и контрольная сумма архива package-<имя>.tar (archive_sha256)
required_files Файлы, которые обязаны быть на месте: файл правил, скрипт каждого компонента и его стили, если правило их объявляет; у каждого — SHA-256 и размер
inventory Число компонентов и правил; для каждого тега — правило, папка, наличие JS и CSS, связи
package_reference Результат сверки со справкой о пакете в выпуске Framework — объект {path, release, status}, где status — agrees, absent, no-release или not-checked. absent — обычное значение для нового пакета, справки о котором в выпуске Framework нет; сборка при этом только предупреждает
files SHA-256 и размер каждого файла пакета
claims production_ready: false: квитанция не объявляет пакет готовым к промышленной эксплуатации

Сборку и квитанцию выполняет одна команда sf-build package: она собирает пакет дважды, выписывает квитанцию и кладёт в выходной каталог собранный каталог smart/, package-receipt.json и детерминированный архив package-<имя>.tar (см. Сборка пакета: sf-build).

Что важно заметить:

  • Квитанция выписывается только для сборки, которая прошла проверку и совпала побайтно в обоих проходах.
  • С параметром --ui квитанция дополнительно сверяет пакет с выпуском Framework: каждая связь правила пакета ведёт к правилу пакета или выпуска, ни один тег пакета не совпадает с тегом Framework, а справка о пакете в выпуске (distr/core/contracts/packages/<имя>.package.json), если она есть, совпадает с правилами пакета. Отсутствие справки — предупреждение, а не ошибка.
  • Проект закрепляет выпуск Framework и пакет вместе (см. Версии: как закрепить выпуск). В своей записи он хранит из квитанции package, package_source.revision, framework.release, output.manifest_sha256 (или output.archive_sha256) и контрольные суммы required_files; проверка проекта сверяет с ними файлы, которые отдаёт сервер.
  • Чтобы перевести пакет на новый выпуск Framework, сначала выходит выпуск Framework; затем framework.lock.json пакета указывает на ревизию исходников этого выпуска, пакет проходит свои тесты, собирается заново и получает новую квитанцию.

Что остаётся во Framework: порты хоста и их наборы проверок, рендереры полей и части редактора композиции. Компонент продукта работает с данными через публичный порт Framework (см. Порт хоста и Порты и наборы проверок), поэтому приложение реализует и проверяет свой хост по открытому контракту.

Сборка пакета: sf-build

sf-build — инструмент, которым собираются Framework и пакеты компонентов. Он лежит в репозитории ui-builder и состоит из командной строки (bin/sf-build.js) и Node API (libs/api.js). Командная строка только разбирает параметры и вызывает те же функции API, поэтому оба способа дают один и тот же результат.

Доступ. Репозитории ui-builder и ui-source открыты и распространяются по лицензии Apache 2.0, как и поставка ui. Сборка пакета требует обе рабочие копии (см. «Условия запуска» ниже). Пакет собирается из открытых исходников для выпусков, начиная с ui-82fc0ba882ba: их ревизии исходников лежат в simai/ui-source. Ревизии более ранних выпусков хранятся в закрытом архиве истории исходников, и пакет под такой выпуск собирается только с доступом к нему, который даёт команда Framework.

sf-build проверяет устройство пакета, правила, воспроизводимость и квитанцию. Манифесты компонентов он не проверяет: соответствие манифеста схеме 2.5.0, которую закрепляет стандарт пакета (требование manifest-conforms, см. Пакет компонентов (simai.component-package)) держат тесты пакета.

Команды

Команда Что делает Что кладёт в --out
sf-build package Собирает пакет дважды поверх ревизии исходников Framework, закреплённой в framework.lock.json, сравнивает обе сборки и выписывает квитанцию smart/…, package-receipt.json, package-<имя>.tar
sf-build framework Собирает Core, компоненты, утилиты и Smart-компоненты из рабочей копии ui-source дважды и сравнивает обе сборки core/, component/, utility/, smart/ и отчёт build-report.json
sf-build verify package, sf-build verify framework Только двойная сборка и сравнение Ничего; параметр --workspace сохраняет обе сборки
sf-build receipt --report <report.json> Выписывает квитанцию для уже проверенной сборки пакета по её отчёту С --out — то же, что sf-build package

sf-build --help перечисляет все параметры. Основные из них: --config, --name, --package-root, --package-revision, --package-repository, --ui-source, --ui, --out, --replace-out, --workspace, --keep-workspace, --json.

Файл настроек sf-build.config.json

Продукт хранит рядом с папкой пакета или в корне репозитория файл sf-build.config.json (формат simai.sf-build.config, файл схемы schemas/sf-build.config.v1.schema.json в ui-builder). Пример собирает пакет acme из папки resources/ui:

JSON
{
  "schema": "simai.sf-build.config.v1",
  "package": { "name": "acme", "kind": "components", "path": "resources/ui" },
  "framework": { "source": "../ui-source" },
  "out": "public/vendor/acme-ui"
}
Поле Обязательно Что задаёт
schema да Имя формата simai.sf-build.config с меткой версии, как в примере (см. Имена и версии)
package.name да Имя пакета: ключ в SF_BOOT_CONFIG.packages и имя, которое регистрирует файл правил. Строчные латинские буквы, цифры и дефис; начинается с буквы
package.kind да Вид пакета: components — пакет компонентов
package.path нет Папка пакета (framework.lock.json и src/smart/<папка>/). По умолчанию — каталог файла настроек
package.revision нет Коммит репозитория пакета, который собирается. По умолчанию HEAD. Сборка читает только закоммиченные файлы, а не рабочее дерево
package.repository нет Идентификатор репозитория для квитанции, например simai/acme. По умолчанию берётся из удалённого репозитория origin на GitHub
framework.source нет Рабочая копия ui-source, в которой есть ревизия из framework.lock.json пакета
framework.ui нет Рабочая копия ui: квитанция называет выпуск, собранный из закреплённой ревизии, и сверяет с ним пакет. Выпуск ищется по записям о выпусках в рабочем дереве, поэтому копия стоит на коммите, где запись уже есть, — на текущей ветке main (см. Выпуск и запись о выпуске)
out нет Выходной каталог
workspace нет Каталог для двух сборок; при каждом запуске новый. Лежит вне ui-builder, вне репозитория пакета и вне ui-source. По умолчанию — временный каталог

Правила файла настроек:

  • других полей схема не принимает: файл с лишним полем отклоняется;
  • относительные пути отсчитываются от каталога, в котором лежит файл;
  • параметр командной строки или API важнее переменной окружения (SF_BUILD_UI_SOURCE, SF_BUILD_UI), а переменная окружения важнее файла. Так сборка на сервере указывает свои рабочие копии, не меняя файл;
  • без --config команды package и verify package берут sf-build.config.json из текущего каталога, если он там есть.

Выходной каталог --out

--out (или поле out) — каталог, куда кладётся результат. Для пакета там оказываются:

  • smart/ — собранные компоненты (smart/<папка>/js/<папка>.js, smart/<папка>/css/<папка>.css) и файл правил smart/rule.js. Этот каталог страница объявляет как SF_BOOT_CONFIG.packages.<имя>.base (см. Пакеты компонентов);
  • package-receipt.json — квитанция пакета (см. Пакеты компонентов продуктов);
  • package-<имя>.tar — детерминированный архив той же сборки.

Правила выходного каталога:

  • результат собирается рядом во временном каталоге, перепроверяется по контрольным суммам квитанции и только после этого занимает место --out;
  • непустой --out заменяется только с параметром --replace-out и только если в нём лежит файл, который кладёт сам sf-build (package-receipt.json или build-report.json). Каталог, который sf-build не создавал, не удаляется;
  • --out не может содержать сборщик, папку пакета или рабочую копию ui-source и не может лежать в рабочем каталоге сборки;
  • рабочий каталог --workspace ещё не существует и лежит вне ui-builder, вне всего репозитория пакета и вне ui-source. Каталог внутри репозитория пакета (например, build/ рядом с исходником) отклоняется с кодом 2 (USAGE) и сообщением: workspace root must be outside the builder, the package repository and ui-source;
  • sf-build package требует --out или --workspace. Без --out сборка и квитанция остаются в рабочем каталоге;
  • временный рабочий каталог удаляется после успешного запуска, который положил результат в --out, и сохраняется после ошибки для разбора.

Результат --json

С параметром --json команда печатает в стандартный вывод один JSON-документ в формате simai.sf-build.result. Node API возвращает тот же объект. Без --json команда пишет ход работы в поток ошибок и краткий итог в конце.

Поле Что значит для вызывающей сборки
status PASS или FAIL — единственный признак успеха
exit_code Код завершения (таблица ниже)
error null при успехе; иначе {code, message} — причина отказа
out.runtime Путь к <out>/smart: его продукт отдаёт как SF_BOOT_CONFIG.packages.<имя>.base
out.receipt Путь к <out>/package-receipt.json: его продукт закрепляет
out.archive Путь к архиву package-<имя>.tar
output.manifest_sha256, output.archive_sha256 Контрольные суммы списка файлов и архива — те же, что в квитанции
framework.release Выпуск Framework, собранный из закреплённой ревизии, или null, если он не определён
package_reference Результат сверки со справкой о пакете в выпуске (см. Пакеты компонентов)
warnings Предупреждения, которые не остановили сборку

Коды завершения

Код Что произошло error.code
0 Собрано, обе сборки совпали, квитанция выписана, результат положен —
1 Сборка не прошла или сборки различаются BUILD_FAILED, NOT_REPRODUCIBLE, OUTPUT_MISMATCH
2 Ошибка параметров, файла настроек или выходного каталога USAGE, CONFIG_INVALID, KIND_NOT_SUPPORTED, OUT_CONFLICT, WORKSPACE_CONFLICT
3 Квитанция отклонила пакет: он расходится с выпуском Framework RECEIPT_REFUSED
4 Окружение не подходит UNSUPPORTED_NODE, TOOL_MISSING, BUILDER_NOT_A_CHECKOUT

Node API

Модуль <ui-builder>/libs/api.js экспортирует функции buildPackage, verifyPackage, buildFramework, verifyFramework, writeReceipt, loadConfig и validateConfig, а также EXIT_CODES, RESULT_SCHEMA и SfBuildError. Имена параметров — параметры командной строки в верблюжьей записи: packageRoot, packageRevision, packageRepository, uiSource, ui, out, replaceOut, workspace, keepWorkspace; кроме них — config, cwd (основа относительных путей), env и onProgress(message). Пример собирает пакет из сценария сборки продукта на Node.js (модуль ES, файл build-ui.mjs):

JavaScript
import sfBuild from '/path/to/ui-builder/libs/api.js';

const result = await sfBuild.buildPackage({
  config: 'sf-build.config.json',
  out: 'public/vendor/acme-ui',
  replaceOut: true,
  onProgress: (message) => console.error(message),
});

if (result.status !== 'PASS') {
  throw new Error(`${result.error.code}: ${result.error.message}`);
}

Что важно заметить: функция не бросает исключение при ожидаемом отказе — ошибке сборки, отклонённой квитанции или неверном параметре. Она возвращает объект с status: "FAIL", поэтому сборка продукта проверяет status.

Как сборка продукта вызывает sf-build

Сборка продукта вызывает sf-build одним из двух способов:

  • из своего сценария сборки — командой node <ui-builder>/bin/sf-build.js package --replace-out --json, запущенной в каталоге с sf-build.config.json; результат читается из стандартного вывода как JSON;
  • из своего кода на Node.js — через buildPackage (пример выше).

После успешной сборки продукт отдаёт каталог out.runtime как SF_BOOT_CONFIG.packages.<имя>.base рядом с выпуском Framework, который называет квитанция, и закрепляет квитанцию out.receipt вместе с выпуском (см. Версии: как закрепить выпуск).

Условия запуска

  • sf-build запускается из рабочей копии репозитория ui-builder, полученной через git clone или лежащей рядом локально, с установленными зависимостями (yarn install --frozen-lockfile). Инструмент записывает в каждый отчёт коммит сборщика; копия без .git отклоняется с кодом BUILDER_NOT_A_CHECKOUT;
  • сборщик закрепляют, как выпуск: выпуск Framework собран коммитом ui-builder из поля build_inputs.builder.commit своей записи о выпуске (см. Выпуск и запись о выпуске), и пакет к этому выпуску собирают тем же коммитом или более новым; квитанция записывает коммит в поле builder;
  • нужны Node.js версии 20.19.0 или новее и git;
  • квитанцию выписывает python3: он нужен командам package и receipt;
  • сборке пакета нужна рабочая копия ui-source, в которой есть ревизия, закреплённая в framework.lock.json пакета (--ui-source, SF_BUILD_UI_SOURCE или framework.source);
  • каждая из двух сборок устанавливает зафиксированные зависимости сборщика заново, поэтому нужен кеш Yarn или доступ к сети.

Пакет темы

Кроме пакета компонентов sf-build собирает пакет темы — свои цвета сайта или продукта, посчитанные так же, как Framework считает собственные. Пакет темы — папка с двумя файлами:

  • framework.lock.json — ревизия ui-source, чьи правила темы берутся, как у пакета компонентов;
  • theme.json — {"schema": "simai.framework.theme-source", "schema_version": 1} и либо color (#rgb или #rrggbb), либо hue и chroma; необязательные selector (по умолчанию :root) и palettes — свои {hue, chroma} для отдельных палитр (primary, secondary, tertiary, neutral, error, warning, success, info).
JSON
{"schema": "simai.framework.theme-source", "schema_version": 1, "color": "#2e7d32", "selector": ":root"}

Сборка — модуль src/core/js/theme-palette.js закреплённой ревизии, тот же расчёт, что у генератора темы: дважды, с побайтным сравнением. Результат в --out:

Файл Что в нём
theme/theme.css одно правило переменных темы под selector
theme/theme.json тема целиком: каждая палитра и её тона
theme-receipt.json квитанция simai.framework.theme-receipt: из чего собрано и хеши файлов
Bash
node <ui-builder>/bin/sf-build.js package --kind theme \
  --package-root brand-theme --package-revision <коммит> \
  --ui-source <ui-source> --out build/brand-theme --json

Вид пакета задают --kind theme или package.kind: "theme" в sf-build.config.json. Проект подключает theme/theme.css после core.css.

Пакет larena для проекта без Larena

Каждая сборка пакета larena публикуется выпуском открытого репозитория simai/larena-ui: выпуск называется larena- и первыми двенадцатью знаками коммита пакета. В выпуске три файла: архив package-larena.tar, его SHA-256 в package-larena.tar.sha256 и квитанция package-receipt.json, которая называет выпуск Framework, рядом с которым пакет работает. Сборку для своего выпуска Framework выбирают по квитанции: подходит выпуск репозитория, в квитанции которого framework.release равно выпуску проекта. Проект без Larena берёт пакет оттуда:

Bash
commit=5f33ba576aebde377d5195ec71836eb4430aa84d
tag="larena-${commit:0:12}"
gh release download "$tag" --repo simai/larena-ui \
  --pattern 'package-larena.tar*' --pattern package-receipt.json
shasum -a 256 -c package-larena.tar.sha256
mkdir -p "public/assets/larena/$commit"
tar -xf package-larena.tar -C "public/assets/larena/$commit"

Без gh те же файлы скачиваются по адресу https://github.com/simai/larena-ui/releases/download/<выпуск>/<файл>. Архив разворачивает папку smart/; её адрес и объявляют на странице: SF_BOOT_CONFIG.packages.larena = {base: '/assets/larena/<коммит пакета>/smart'}. Если SHA-256 не совпадает, архив не разворачивают.

Ту же сборку можно воспроизвести из исходников командой sf-build package при тех же условиях запуска: архив получится байт в байт тем же, и его SHA-256 совпадёт с опубликованным. Нужны три открытых репозитория на закреплённых ревизиях: simai/ui-builder (сборщик; установка зависимостей и команда — в его README), simai/ui-source (исходники Framework на ревизии, которую закрепляет components/framework.lock.json пакета, для этого выпуска — 3029d8abda3899f055d91e1599e1c19a969e4369) и simai/larena-ui (исходник пакета). Пример воспроизведения — для выпуска ui-106d5901f8c3; <ui-builder>, <ui-source> и <ui> — пути к рабочим копиям, <ui> стоит на текущей ветке main.

  1. Сборка. Папка пакета — components репозитория simai/larena-ui, ревизия — коммит пакета, собранного для выпуска (см. Выпуск и запись о выпуске):

    Сборщик стоит на коммите, которым собран пакет (поле сборщика в его квитанции); он может быть новее сборщика выпуска Framework. Для этого пакета — git -C <ui-builder> checkout 7d57d9b45549e7f6b7bc4e615ccf80a3f35cedc3.

    Bash
    git clone https://github.com/simai/larena-ui.git
    git -C larena-ui checkout 5f33ba576aebde377d5195ec71836eb4430aa84d
    node <ui-builder>/bin/sf-build.js package --name larena \
      --package-root larena-ui/components \
      --package-revision 5f33ba576aebde377d5195ec71836eb4430aa84d \
      --package-repository simai/larena-ui \
      --ui-source <ui-source> --ui <ui> --out build/larena --json
    
  2. Проверка квитанции. Команда завершается с кодом 0 и status: "PASS". В build/larena/package-receipt.json поле framework.release равно ui-106d5901f8c3, package_source.revision — коммиту из шага 1, а package_reference.status — agrees.

  3. Подключение. Каталог build/larena/smart кладут в публичную папку проекта под путём с коммитом пакета, например public/assets/larena/5f33ba576aebde377d5195ec71836eb4430aa84d/smart/, и объявляют до core.js:

    JavaScript
    window.SF_BOOT_CONFIG = {
      packages: {larena: {base: '/assets/larena/5f33ba576aebde377d5195ec71836eb4430aa84d/smart'}},
    };
    

    В файл блокировки проекта переписывают output.manifest_sha256 из квитанции этой сборки (см. Версии).

Loader

Loader — модуль Core, который подключается вместе с core.js (отдельного файла загрузчика проекту подключать не нужно). После запуска он доступен как SF.Loader и делает три вещи:

  • находит на странице классы утилит и компонентов и теги Smart-компонентов — по правилам загрузки из поставки;
  • загружает только нужные модули, по умолчанию в сжатом виде: класс sf-button подтягивает компонент кнопки, тег <sf-button> — Smart-кнопку, её зависимости и общую основу Smart-компонентов;
  • следит за страницей и подгружает то, что появилось позже, например после ответа сервера.

Где лежат файлы, Loader узнаёт из глобальной переменной window.sfPath (каталог distr/ поставки), заданной до core.js; Smart-компоненты он берёт из <sfPath>/smart/. Поведение загрузки настраивается объектом window.SF_BOOT_CONFIG; в нём же объявляются пакеты компонентов, например пакет продукта (см. Пакеты компонентов продуктов). Все настройки и их значения по умолчанию — см. Глобальные настройки; как Loader находит и загружает модули — Как работает Loader; пакеты компонентов — Пакеты компонентов.

Документация

Документация (ui-doc) — сайт с руководством и тремя справочниками: утилиты, компоненты, Smart-компоненты. Руководство объясняет, справочники перечисляют точные классы, настройки и события. Документация привязана к конкретному выпуску поставки и проверяет, что её страницы не отстали от кода. Для ИИ сайт публикует машиночитаемый индекс ai.json и Markdown-версии страниц.

Поиск по документации

Введите минимум 2 символа

    Настройки

    Тема
    Размер шрифта
    Ширина страницы