ADR-UI-001. Технологический стек фронтенда

ADR Версия: 1.0 accepted

Запускается фронтенд ICD (src-ui). Нужно зафиксировать базовый стек UI: фреймворк, подход к компонентной базе, вспомогательные пакеты — и явно обозначить, что используется, а что сознательно не включается. Ключевая особенность: компонентную базу строим свою, а не берём готовый UI-kit, с прицелом на переиспользование набора в других проектах.

⟨/⟩ Исходник

1. Контекст и постановка задачи

Фронтенд ICD — тонкий клиент (браузерное веб-приложение), запускается с нуля, наследия нет. Нужно зафиксировать базовый стек, чтобы дальнейшие решения принимались осознанно, а не по инерции.

Дополнительное требование, определяющее выбор: компонентную базу (от элементарных кнопок и полей до крупных таблиц с сортировкой и редактированием ячеек) хотим сделать своей и переиспользуемой в других проектах. Это прямой довод против готового UI-kit как фундамента — иначе каждый проект-потребитель тянул бы за собой стороннюю библиотеку и её визуальный язык.

2. Драйверы решения

  1. Актуальность — новый проект стартует на самой свежей стабильной версии Angular.
  2. Переносимость своего UI-набора — компоненты должны безболезненно выноситься в другой проект (целиком или по одному), без завязки на доменный код и без чужой темы.
  3. Контроль над визуалом и API — свой дизайн-язык и свой контракт компонентов, а не адаптация под чужую тему.
  4. Минимум зависимостей — каждая внешняя библиотека несёт цену поддержки; подключаем только то, что дорого и рискованно писать самим.
  5. Покрытие официальной документацией — стек опирается на Angular и его CDK, без редких пакетов.

3. Рассмотренные варианты

4. Решение

Выбран Вариант B: Angular (последний стабильный) + собственный набор компонентов на @angular/cdk, без готового UI-kit.

4.1. Базовые зависимости

Пакет Версия Назначение
@angular/* 22.x Фреймворк.
@angular/cdk 22.x Headless-примитивы (overlay, a11y/focus-trap, sticky-таблица, virtual-scroll, drag-drop) — фундамент собственных компонентов, без навязанного визуала.
rxjs 7.x Реактивные потоки: HTTP, мост в сигналы (toSignal).
date-fns 4.x Работа с датами, локаль ru (при работе с таймзонами добавляется date-fns-tz).
sass (SCSS) Препроцессор стилей. Дизайн-токены — на CSS custom properties (тема задаётся переменными снаружи, что и делает набор переносимым).

4.2. Формы

Формы — на Signal Forms (@angular/forms/signals), а не на Reactive Forms. Фронт строится signals-first: значения и валидность формы — сигналы, без моста к реактивным потокам. В актуальной версии Angular это стабильный публичный API, так что выбор не противоречит драйверу стабильности.

4.3. Собственный набор компонентов — принципы переносимости

Компоненты живут в src-ui/src/app/ui/ (пока не отдельная npm-библиотека), но проектируются так, чтобы выноситься в другой проект без переписывания:

  1. Зависимости только «вниз»: Angular, @angular/cdk, свои ui-примитивы, дизайн-токены. Ни одного импорта из доменного/прикладного кода проекта.
  2. Ноль доменных знаний: данные — через input()/generics, поведение — через output()/колбэки.
  3. Стили на дизайн-токенах (CSS custom properties), без хардкода цветов; тема — снаружи.
  4. Гранулярность и слабая связность: компонент — своя папка со своим barrel; один компонент не тянет весь набор.
  5. Единый alias и barrel-экспорты (@ui/*) — набор перемещается одним движением.
  6. Минимум внешних зависимостей, standalone-компоненты.

4.4. Что не используем

5. Положительные следствия

6. Отрицательные следствия и компромиссы

7. Проверка

8. Открытые вопросы / отложено

Связанные артефакты

Документы