mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
67 lines
5.8 KiB
Markdown
67 lines
5.8 KiB
Markdown
# Модули SLM
|
||
|
||
> Пояснение нормативной модели модулей SLM.
|
||
|
||
Модуль является основной архитектурной единицей SLM. Он размещается в отдельной папке, но может состоять только из публичной точки входа и одного файла реализации.
|
||
|
||
## Связанные правила
|
||
|
||
- [`SLM-MODULE-A004`](../rules/registry.md#slm-module-a004)
|
||
- [`SLM-MODULE-A014`](../rules/registry.md#slm-module-a014)
|
||
- [`SLM-MODULE-R006`](../rules/registry.md#slm-module-r006)
|
||
- [`SLM-MODULE-R011`](../rules/registry.md#slm-module-r011)
|
||
- [`SLM-MODULE-R012`](../rules/registry.md#slm-module-r012)
|
||
- [`SLM-ENVIRONMENT-R016`](../rules/registry.md#slm-environment-r016)
|
||
- [`SLM-ENVIRONMENT-R017`](../rules/registry.md#slm-environment-r017)
|
||
- [`SLM-ENVIRONMENT-R018`](../rules/registry.md#slm-environment-r018)
|
||
- [`SLM-ENVIRONMENT-R019`](../rules/registry.md#slm-environment-r019)
|
||
|
||
## Владение
|
||
|
||
Каждая самостоятельная ответственность имеет одного модуля-владельца. Модуль определяет её публичный API, зависимости, состояние, область жизни и внутреннее устройство независимо от того, в каком файле выполняется конкретный код.
|
||
|
||
Точки входа `app` и нормативные ресурсы `shared` являются единственными немодульными исключениями. Остальной код внутри SLM root либо принадлежит существующему модулю, либо образует новый модуль.
|
||
|
||
## Публичный API
|
||
|
||
Модуль предоставляет один логический публичный API. По умолчанию он представлен корневым `index`, который служит основным barrel. Если реальные потребители требуют разделить несовместимые среды выполнения, модуль добавляет один или несколько фасетов `client`, `browser` и `server`.
|
||
|
||
Объявленные фасеты вместе образуют один публичный API и не считаются deep imports. Внешний код использует модуль только через них. Сам API открывает только контракт, необходимый реальным внешним потребителям; внутренние механизмы, изменяемое состояние и детали жизненного цикла остаются закрытыми.
|
||
|
||
```text
|
||
auth/
|
||
├── index.ts # Универсальный фасет
|
||
├── client.ts # Необязательная клиентская framework-граница
|
||
├── browser.ts # Необязательная browser-only граница
|
||
├── server.ts # Необязательная server-only граница
|
||
└── ... # Внутренняя реализация
|
||
```
|
||
|
||
`index` экспортирует публичные типы и runtime-код, который одинаково допустимо выполнять при серверном рендеринге, включая RSC, и в клиентском runtime. Он не реэкспортирует специализированные фасеты.
|
||
|
||
`client` экспортирует Client Components, hooks, Providers и другой код, который не может выполняться как RSC. Такой код может быть отмечен директивой вроде `use client`.
|
||
|
||
`browser` экспортирует browser-only возможности и lazy-функциональность. Потребитель подключает этот фасет только динамически через поддерживаемую фреймворком границу с отключённым SSR.
|
||
|
||
`server` экспортирует только server-only возможности. `index`, `client` и `browser` не импортируют и не реэкспортируют его код.
|
||
|
||
Фасет не создаётся для симметрии или будущей потребности. Один публичный runtime-export размещается в минимально подходящем фасете и не дублируется между фасетами.
|
||
|
||
## Внутреннее устройство
|
||
|
||
Модуль может содержать корневые файлы, сегменты, компоненты и [вложенные модули](./nested-modules.md). Внутри своей границы он может использовать относительные импорты и не обязан обращаться к собственному публичному API; точную форму внутренних импортов определяет стайлгайд.
|
||
|
||
SLM не требует полного каркаса или обязательного каталога сегментов. Файлы фасетов являются публичными точками входа, а не сегментами или самостоятельными модулями.
|
||
|
||
## Визуальный модуль
|
||
|
||
Визуальный модуль обычно имеет корневой компонент, который экспортируется через публичный API.
|
||
|
||
```text
|
||
button/
|
||
├── button.tsx
|
||
└── index.ts
|
||
```
|
||
|
||
Корневой компонент остаётся компонентом, а владельцем ответственности является модуль `button`.
|