Files
slm-design/DRAFT/architecture/dependencies.md
S. Gromov 691069af8e sync
2026-08-10 09:12:22 +03:00

88 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Зависимости 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
```