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

5.2 KiB
Raw Blame History

Зависимости SLM

Пояснение нормативной модели зависимостей SLM.

Матрица слоёв задаёт допустимые зависимости между модулями.

Что считается зависимостью

  • Обычный импорт, импорт типа и реэкспорт одинаково создают архитектурную зависимость.
  • Импорт между файлами одного модуля не пересекает модульную границу.
  • Импорт любого внутреннего файла, сегмента или компонента считается зависимостью ближайшего модуля-владельца.
  • Вложенный модуль имеет собственную границу зависимостей.
  • Группы, сегменты и компоненты не имеют самостоятельных границ зависимостей.

Точка входа фреймворка не является модулем. Её импорты участвуют в проверке направления слоёв.

Ресурс shared также не является модулем. Его прямой импорт участвует в проверке направления слоёв, но не нарушает требование о публичном API модуля.

Допустимые связи

  • Модуль может импортировать модули своего слоя и слоёв, разрешённых нормативной матрицей.
  • Модули одного слоя могут импортировать друг друга.
  • Промежуточный слой не является обязательным посредником.
  • infra может импортировать ui для визуального представления технической возможности; ui не импортирует infra.

Модуль слоя domains может импортировать публичный API другого разрешённого модуля. Runtime- и type-only импорты одинаково создают архитектурную зависимость, а циклические зависимости запрещены.

// domains/orders
import type { Product } from '@/domains/catalog'

SLM не требует отдельного механизма инъекции между модулями слоя domains.

Матрица слоёв определена в Слоях.

Связанные правила

Публичный API

// Допустимо
import { Button } from '@/ui/button'

// Недопустимо
import { Button } from '@/ui/button/button'

Если модуль объявляет специализированный фасет, его путь также является публичным:

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 могут использовать универсальную внутреннюю реализацию, но не импортируют друг друга.

// 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.

Циклы

ui/modal → ui/button → ui/icon
ui/icon -/→ ui/modal