mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
chore: sync
This commit is contained in:
@@ -10,28 +10,27 @@
|
||||
Слой → [Группа*] → Модуль → [Сегмент*]
|
||||
```
|
||||
|
||||
Группа классифицирует несколько модулей внутри слоя. Сегмент классифицирует код одного модуля. Ни группа, ни сегмент не являются владельцами.
|
||||
Группа классифицирует модули внутри слоя. Сегмент классифицирует код одного модуля. Ни группа, ни сегмент не являются владельцами.
|
||||
|
||||
Все файлы, компоненты, состояние, зависимости и код жизненного цикла сегмента принадлежат родительскому модулю. Исключением является только вложенный модуль, который начинает собственную границу владения.
|
||||
Все файлы, framework-компоненты, состояние, зависимости и lifecycle-код сегмента принадлежат ближайшему модулю. Исключением является только вложенный модуль, который начинает собственную границу владения.
|
||||
|
||||
## Назначение
|
||||
|
||||
Сегмент используется, когда группировка внутренних файлов по назначению упрощает навигацию. Набор и названия сегментов определяет проект.
|
||||
|
||||
Возможная структура:
|
||||
|
||||
```text
|
||||
profile/
|
||||
├── index.ts
|
||||
├── profile.tsx
|
||||
├── hooks/ # Возможный сегмент
|
||||
├── services/ # Возможный сегмент
|
||||
├── stores/ # Возможный сегмент
|
||||
├── types/ # Возможный сегмент
|
||||
└── ui/ # Возможный сегмент
|
||||
├── index.ts # Публичный фасет
|
||||
├── profile.tsx # Главная реализация
|
||||
├── components/ # Возможный сегмент
|
||||
├── hooks/ # Возможный сегмент
|
||||
├── services/ # Возможный сегмент
|
||||
├── stores/ # Возможный сегмент
|
||||
├── types/ # Возможный сегмент
|
||||
└── styles/ # Возможный сегмент
|
||||
```
|
||||
|
||||
Ни один из показанных сегментов не обязателен. Маленький модуль может хранить реализацию в корне без дополнительных каталогов.
|
||||
Ни один сегмент не создаётся заранее. Модуль может обойтись без сегментов, если помимо публичных фасетов содержит только один главный implementation- или assembly-файл, однозначно выражающий его ответственность. Любая остальная реализация размещается в подходящих сегментах. Если главный файл нельзя определить уверенно, вся реализация остаётся в сегментах.
|
||||
|
||||
Сегмент:
|
||||
|
||||
@@ -41,52 +40,67 @@ profile/
|
||||
- не является узлом графа зависимостей;
|
||||
- не импортируется внешним кодом как отдельная архитектурная сущность.
|
||||
|
||||
Локальный `index.ts` может использоваться во внутренней единице сегмента, например в каталоге компонента. Он не превращает эту единицу или сегмент в модульную границу.
|
||||
Локальный `index.ts` может использоваться во внутренней единице сегмента. Он не превращает эту единицу или сегмент в модульную границу.
|
||||
|
||||
## Компоненты и вложенные модули
|
||||
## Framework-компоненты
|
||||
|
||||
Сегмент может содержать компоненты и вспомогательные файлы родительского модуля. Компонент вправе иметь локальные `styles/`, `types/`, `tests/` и внутренний `index.ts`; всё это остаётся реализацией ближайшего модуля.
|
||||
Framework-компоненты являются обычным внутренним кодом модуля. Они могут выполнять визуальные и невизуальные роли, включая Provider, Guard или Error Boundary, если используемый фреймворк считает соответствующую сущность компонентом.
|
||||
|
||||
Помимо опционального главного framework-файла в корне, остальные компонентные единицы размещаются на одном внутреннем уровне относительно модуля. Каталог такой единицы может содержать локальные `styles`, `types`, `hooks`, `tests` и внутренний `index.ts`, но не содержит другие компонентные единицы или вложенные модули.
|
||||
|
||||
```text
|
||||
header/ # Модуль
|
||||
└── components/ # Сегмент
|
||||
└── button-submit/ # Компонент
|
||||
├── button-submit.tsx
|
||||
├── styles/
|
||||
│ └── button-submit.module.css
|
||||
├── types/
|
||||
│ └── button-submit.types.ts
|
||||
└── index.ts # Внутренняя точка входа
|
||||
header/ # Модуль
|
||||
├── index.ts # Публичный фасет
|
||||
├── header.tsx # Главная реализация
|
||||
└── components/ # Сегмент
|
||||
├── button-submit/
|
||||
│ ├── index.ts # Локальная точка входа
|
||||
│ ├── button-submit.tsx
|
||||
│ ├── styles/
|
||||
│ ├── types/
|
||||
│ └── hooks/
|
||||
└── icon.tsx # Соседняя компонентная единица
|
||||
```
|
||||
|
||||
`ButtonSubmit` может рендерить `Icon`, но их файловые области не вкладываются друг в друга. Ограничение относится к файловой структуре, а не к runtime-дереву.
|
||||
|
||||
Внешний код не импортирует `components/button-submit`. Если компонент нужен снаружи, модуль-владелец реэкспортирует его через собственный публичный фасет.
|
||||
|
||||
Сегмент также может содержать вложенные модули. В отличие от остальных файлов сегмента, каждый вложенный модуль сам владеет отдельной ответственностью и имеет публичный API и границу зависимостей.
|
||||
## Вложенные модули
|
||||
|
||||
Сегмент может содержать вложенные модули. В отличие от остальных файлов сегмента, каждый вложенный модуль владеет отдельно сформулированной подответственностью и имеет публичный API и границу зависимостей.
|
||||
|
||||
```text
|
||||
landing/ # Родительский модуль
|
||||
└── parts/ # Сегмент
|
||||
└── modules/ # Сегмент
|
||||
└── hero/ # Вложенный модуль
|
||||
├── hero.tsx
|
||||
└── index.ts
|
||||
├── index.ts # Публичный фасет вложенного модуля
|
||||
├── hero.tsx # Главная реализация hero
|
||||
└── modules/ # Допустимая модульная рекурсия
|
||||
└── media/
|
||||
└── index.ts
|
||||
```
|
||||
|
||||
Имя `parts` является примером, а не обязательным соглашением SLM.
|
||||
Компонентный каталог не содержит `components` или `modules`. Рекурсивная структурная вложенность допускается только через вложенные модули. Имена `components` и `modules` являются примерами локального стайлгайда, а не обязательными соглашениями SLM.
|
||||
|
||||
## Выбор границы
|
||||
## Выбор размещения
|
||||
|
||||
| Ситуация | Решение |
|
||||
|---|---|
|
||||
| Код относится к существующему владельцу и группируется только по назначению | Сегмент |
|
||||
| Части нужна собственная ответственность, API, зависимости, состояние или область жизни | Модуль |
|
||||
| Несколько модулей слоя нужно классифицировать для навигации | Группа |
|
||||
| Нескольким файлам не нужна отдельная группировка | Оставить в корне модуля |
|
||||
| Код относится к существующему владельцу и группируется по назначению | Сегмент |
|
||||
| Вспомогательный код нужен только одной компонентной единице | Колоцировать в её локальном каталоге |
|
||||
| Выделена отдельная framework-компонентная единица | Разместить на общем внутреннем уровне модуля |
|
||||
| Код нужен нескольким внутренним единицам модуля | Поднять в ближайший общий сегмент |
|
||||
| Появилась самостоятельная связная подответственность | Создать вложенный модуль |
|
||||
| Файл однозначно является главной реализацией или сборкой ответственности | Допустимо разместить в корне модуля |
|
||||
| Файл не является главным или его роль неоднозначна | Разместить в подходящем сегменте |
|
||||
|
||||
Размер каталога и количество файлов не определяют выбор между сегментом и модулем.
|
||||
Размер каталога и количество файлов не определяют модульную границу. Её создаёт только самостоятельная ответственность и назначение нового владельца.
|
||||
|
||||
## Связанные правила
|
||||
|
||||
- [`SLM-SEGMENT-R008`](../rules/registry.md#slm-segment-r008)
|
||||
- [`SLM-MODULE-A004`](../rules/registry.md#slm-module-a004)
|
||||
- [`SLM-COMPONENT-R009`](../rules/registry.md#slm-component-r009)
|
||||
- [`SLM-MODULE-R020`](../rules/registry.md#slm-module-r020)
|
||||
- [`SLM-MODULE-R021`](../rules/registry.md#slm-module-r021)
|
||||
- [`SLM-NESTED_MODULE-A010`](../rules/registry.md#slm-nested_module-a010)
|
||||
|
||||
Reference in New Issue
Block a user