dma check
Жёсткая проверка графа зависимостей для CI — установка, запуск и разбор правил.
dma check — главная команда DMA. Она строит граф импортов по проекту и проверяет архитектурные правила. Если что-то нарушено — ненулевой код выхода, CI падает.
Линтеры в редакторе полезны, но не заменяют check: циклы, предикаты входящих рёбер и полный граф видит только CLI.
Установка
npm install -D @derived-modular/cliНужен Node.js 18+.
Запуск — только через имя пакета:
npx @derived-modular/cli check
npx @derived-modular/cli check . # явный путь к корню проекта
npx @derived-modular/cli check --format json
npx @derived-modular/cli check --suggest # план безопасных фиксов (без записи)
npx @derived-modular/cli check --fix # применить фиксы, затем снова checkВ package.json:
{
"scripts": {
"dma-check": "npx @derived-modular/cli check ."
}
}По умолчанию CLI ищет дерево src/{app|pages|routes, features, services?, shared} относительно переданного пути.
Коды выхода
| Код | Значение |
|---|---|
0 | Ошибок нет |
1 | Найдены архитектурные нарушения |
2 | Сбой окружения: нет src/, битый tsconfig, неверные аргументы |
В CI обычно достаточно:
npx @derived-modular/cli check .Для GitHub Actions и агентов — --format json (стабильный отчёт version: 1).
Цветной вывод отключается через NO_COLOR=1.
Безопасный autofix (--suggest / --fix)
Механические правки, которые не «придумывают» архитектуру:
| Флаг | Поведение |
|---|---|
--suggest | Печатает план; файлы не трогает |
--fix | Применяет план, затем снова запускает check |
Сейчас поддерживается:
no-barrel— переписать импорты в barrel с однимexport … fromна прямой public path (как ESLint autofix). Сам barrel-файл не удаляется.public-api— переписать deep import на mirroredpublic/<тот-же-относительный-путь>, только если такой файл уже есть.
Нужен один project root (не multi-root discover). Флаги взаимоисключающие. Не создаёт public/ и не вызывает promote.
Что именно проверяется
| Правило | Смысл |
|---|---|
layer-direction | Импорты только вниз: app/pages/routes → features → services → shared |
feature-to-feature | Feature не импортирует другой feature |
public-api | Межмодульные импорты идут в */public/* |
no-barrel | Нет barrel index с реэкспортами внутри модулей |
no-cycle | Граф модулей ацикличен |
feature-has-inbound | Feature с входящими рёбрами от модулей → должен быть в services/ |
service-no-inbound | Service без потребителей среди модулей → нарушение предиката |
Входящие рёбра считаются только от модулей (features/*, services/*). Монтирование из app/, pages/, routes/ promotion не вызывает.
Контекст правил — в Четыре инварианта и Слои. Алгоритм «куда положить файл» — Куда положить файл.
Справочник нарушений
Типичные ruleId из отчёта check и что с ними делать.
| ruleId | Причина | Типичный фикс | Подробнее |
|---|---|---|---|
feature-to-feature | Feature импортирует другой feature | Promotion в services/, перенос в shared/, или связка в корень композиции | Склейка модулей, Куда положить файл |
layer-direction | Импорт вверх по слою (например, feature → app/) | Уберите импорт; передайте данные через props/events из корня композиции | Слои |
public-api | Межмодульный импорт мимо */public/* | Импортируйте */public/<file> напрямую; internal — только relative внутри модуля | Модули |
no-barrel | index.ts с реэкспортами внутри модуля | Удалите barrel; импортируйте конкретные файлы | Почему нет barrel |
no-cycle | Цикл в графе модулей | Вынесите в shared/, promotion в services/, или порт + привязка в app/ | Склейка модулей |
feature-has-inbound | У feature есть входящих рёбер от другого модуля | dma promote <name> --apply, затем пересмотрите public/ | dma promote · Эволюция кода |
service-no-inbound | Service без потребителей среди модулей | Верните размещение рядом в feature или удалите пустой service | Слои |
Код выхода 2 (окружение)
| Симптом | Что проверить |
|---|---|
Нет src/ / нет DMA-корней | Single-app: корень приложения. Корень монорепо: discovery должен найти apps, или --roots / --include-packages |
| Битый tsconfig | paths для @/ в tsconfig приложения |
| Неверные аргументы | npx @derived-modular/cli check --help |
См. Монорепо для нескольких app roots.
Что CLI умеет анализировать
Сканируются статические импорты в:
.ts,.tsx,.js,.jsx,.mjs,.cjs.vue,.svelte,.astro.md,.mdx— импорты в контенте тоже попадают в граф (актуально для doc-apps и MDX-компонентов)
Учитываются import, export … from, import type, динамический import() и require() — в том числе цели next/dynamic и React.lazy.
Алиасы путей подхватываются из tsconfig.json.
Форматы вывода
| Формат | Когда использовать |
|---|---|
human (default) | Локальная разработка |
json | CI, скрипты, AI-агенты |
sarif | GitHub Code Scanning |
npx @derived-modular/cli check --format sarif > dma.sarifcheck vs doctor
dma check | dma doctor | |
|---|---|---|
| Назначение | Жёсткие правила | Мягкие сигналы эволюции |
| Код выхода при находках | 1 | 0 (по умолчанию) |
| Где запускать | CI, pre-push | Локально |
doctor подсказывает shared-candidate, stage-growth, dense-services, orphan-public — но не дублирует ошибки check. Подробнее — на странице dma doctor.
Линтеры — дополнение, не замена
В редакторе можно подключить ESLint, Biome или Oxlint плагины DMA. Они ловят часть правил по одному файлу, но не видят циклы и предикаты входящих рёбер.
Всегда запускайте npx @derived-modular/cli check в CI. Линтеры — для быстрой обратной связи в IDE.
Обзор всех адаптеров — Инструменты: обзор.
Пример для монорепо DMA
Если вы в репозитории derived-modular-architecture:
npx @derived-modular/cli check .