Что такое DMA
Зачем фронтенду правила, которые можно проверить в CI — и почему «у нас и так всё работает» обычно ненадолго.
На старте проекта архитектура почти всегда «ок». Импорты короткие, папок мало, все помнят договорённости. Через полгода-год картина другая: фичи тянут друг друга, utils/ разрастается, на ревью спорят, куда положить файл — и каждый раз побеждает тот, кто громче или кто уже устал.
Проблема не в том, что люди плохие. Проблема в том, что без проверки правила живут только в головах. А головы меняются, дедлайны давят, «на один раз» становится нормой.
Derived Modular Architecture (DMA) — способ разложить фронтенд-код так, чтобы основные ограничения следовали из структуры проекта и импортов, а не из устных договорённостей. И чтобы их можно было проверить командой в CI — так же, как типы или линт.
Почему «и так всё работает» — не аргумент
Пока проект маленький, почти любая схема работает. Сломается не сегодня: сломается, когда:
- кто-то импортирует соседнюю фичу «временно» — и через три месяца это уже невидимый клубок;
- общий код выносят «на будущее» — и появляется свалка хелперов, которую никто не чистит;
- зависимости прячут через
index.tsс реэкспортами — и никто не видит, кто от кого реально зависит.
Ревью это ловит выборочно. В пятницу вечером — почти никогда. DMA как раз про то, чтобы такие вещи не зависели от настроения ревьюера.
Что даёт проверка
Вместе с правилами идёт набор инструментов: @derived-modular/cli для CI, плагины к линтерам (ESLint, Oxlint, Biome) для редактора и навык агента dma для Cursor и других ассистентов — см. AI и агенты.
Идея простая:
- в редакторе — быстрый сигнал, пока пишете код;
- в CI — жёсткая проверка перед слиянием: если нарушили правило, пайплайн падает.
Без этого DMA — просто ещё один гайд по папкам. С проверкой — договорённость, которую нельзя «забыть».
npm install -D @derived-modular/cli
npx @derived-modular/cli check .Как поставить и что именно ловится — в Быстром старте и Обзоре инструментов. Сейчас важнее другое: зачем это вообще.
Как выглядит проект
Правила DMA опираются на понятное дерево:
src/
├── app/ # роуты, layout, склейка экранов
├── features/ # отдельные пользовательские сценарии
├── services/ # общее между сценариями (появляется позже)
└── shared/ # переносимые куски: кнопки, хелперы, типыНа разных фреймворках вместо app/ может быть pages/ или routes/ — смысл тот же: тонкая оболочка, которая собирает экраны, а не хранит всю логику.
Папку services/ не нужно заводить «на вырост». Она появляется при promotion: когда другой модуль должен импортировать этот код (достаточно одного входящих рёбер от features/* или services/*). Монтирование из app/ / pages/ / routes/ promotion не вызывает. До этого код размещают рядом с единственным потребителем.
Подробнее о дереве — Структура проекта.
Несколько простых правил
Без полного списка терминов — суть:
- Зависимости идут сверху вниз: оболочка → сценарии → общее → переносимое.
- Сценарии не импортируют друг друга напрямую — иначе быстро получается клубок.
- Снаружи модуля видно только то, что вынесено явно; без «бочек» с реэкспортами, которые прячут связи.
- Не выносите код «на будущее» — выносите, когда появился второй потребитель.
Развёрнуто — в Четыре инварианта.
Чем DMA не является
Это не новый фреймворк и не запрет думать. React, Vue, Svelte, Astro — как были, так и остаются. DMA не решает за вас, как нарезать продукт на домены, и не выбирает библиотеку состояния.
Он закрывает другое: чтобы базовые границы модулей не размывались сами собой, пока «всё ещё работает».