This commit is contained in:
S. Gromov
2026-08-10 09:12:22 +03:00
parent b5db9e5158
commit 691069af8e
55 changed files with 1519 additions and 3383 deletions

View File

@@ -0,0 +1,66 @@
# Модули 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`.