mirror of
https://github.com/gromlab-ru/slm-design.git
synced 2026-08-22 07:30:16 +03:00
88 lines
5.2 KiB
Markdown
88 lines
5.2 KiB
Markdown
|
|
# Зависимости SLM
|
|||
|
|
|
|||
|
|
> Пояснение нормативной модели зависимостей SLM.
|
|||
|
|
|
|||
|
|
Матрица слоёв задаёт допустимые зависимости между модулями.
|
|||
|
|
|
|||
|
|
## Что считается зависимостью
|
|||
|
|
|
|||
|
|
- Обычный импорт, импорт типа и реэкспорт одинаково создают архитектурную зависимость.
|
|||
|
|
- Импорт между файлами одного модуля не пересекает модульную границу.
|
|||
|
|
- Импорт любого внутреннего файла, сегмента или компонента считается зависимостью ближайшего модуля-владельца.
|
|||
|
|
- Вложенный модуль имеет собственную границу зависимостей.
|
|||
|
|
- Группы, сегменты и компоненты не имеют самостоятельных границ зависимостей.
|
|||
|
|
|
|||
|
|
Точка входа фреймворка не является модулем. Её импорты участвуют в проверке направления слоёв.
|
|||
|
|
|
|||
|
|
Ресурс `shared` также не является модулем. Его прямой импорт участвует в проверке направления слоёв, но не нарушает требование о публичном API модуля.
|
|||
|
|
|
|||
|
|
## Допустимые связи
|
|||
|
|
|
|||
|
|
- Модуль может импортировать модули своего слоя и слоёв, разрешённых нормативной матрицей.
|
|||
|
|
- Модули одного слоя могут импортировать друг друга.
|
|||
|
|
- Промежуточный слой не является обязательным посредником.
|
|||
|
|
- `infra` может импортировать `ui` для визуального представления технической возможности; `ui` не импортирует `infra`.
|
|||
|
|
|
|||
|
|
Модуль слоя `domains` может импортировать публичный API другого разрешённого модуля. Runtime- и type-only импорты одинаково создают архитектурную зависимость, а циклические зависимости запрещены.
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// domains/orders
|
|||
|
|
import type { Product } from '@/domains/catalog'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
SLM не требует отдельного механизма инъекции между модулями слоя `domains`.
|
|||
|
|
|
|||
|
|
Матрица слоёв определена в [Слоях](./layers.md).
|
|||
|
|
|
|||
|
|
## Связанные правила
|
|||
|
|
|
|||
|
|
- [`SLM-LAYER-A002`](../rules/registry.md#slm-layer-a002)
|
|||
|
|
- [`SLM-MODULE-A004`](../rules/registry.md#slm-module-a004)
|
|||
|
|
- [`SLM-DEPENDENCY-A005`](../rules/registry.md#slm-dependency-a005)
|
|||
|
|
- [`SLM-NESTED_MODULE-A010`](../rules/registry.md#slm-nested_module-a010)
|
|||
|
|
- [`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
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// Допустимо
|
|||
|
|
import { Button } from '@/ui/button'
|
|||
|
|
|
|||
|
|
// Недопустимо
|
|||
|
|
import { Button } from '@/ui/button/button'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Если модуль объявляет специализированный фасет, его путь также является публичным:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
import type { Session } from '@/domains/auth'
|
|||
|
|
import { AuthProvider } from '@/domains/auth/client'
|
|||
|
|
import { getServerSession } from '@/domains/auth/server'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Фасеты сред выполнения
|
|||
|
|
|
|||
|
|
Ограничения фасета распространяются на все его runtime-импорты и реэкспорты, включая транзитивные. Type-only import остаётся архитектурной зависимостью, но не добавляет исполняемый код в среду фасета.
|
|||
|
|
|
|||
|
|
`index` не импортирует и не реэкспортирует `client`, `browser` или `server`. `client` может использовать универсальную внутреннюю реализацию модуля, но не импортирует `browser` или `server`. `browser` и `server` могут использовать универсальную внутреннюю реализацию, но не импортируют друг друга.
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// Browser-only фасет подключается только за границей без SSR.
|
|||
|
|
const BrowserEditor = dynamic(
|
|||
|
|
() => import('@/domains/editor/browser').then(({ BrowserEditor }) => BrowserEditor),
|
|||
|
|
{ ssr: false },
|
|||
|
|
)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Обычный статический импорт `@/domains/editor/browser` запрещён даже внутри Client Component. Tree shaking, проверка `typeof window` и обещание не вызывать экспорт при SSR не заменяют динамическую границу с отключённым SSR.
|
|||
|
|
|
|||
|
|
## Циклы
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
ui/modal → ui/button → ui/icon
|
|||
|
|
ui/icon -/→ ui/modal
|
|||
|
|
```
|