Skip to content

Слои архитектуры

Большинство больших фронтенд-кодбейзов оседают на каком-то слоении: app → pages → widgets → features → entities → shared (FSD), или domain → application → infrastructure (clean architecture), или какой-то свой вариант. Обещание одно: можно менять фичу, не трогая нижележащий слой.

Archora проверяет это обещание.

Объявление слоёв

В archora.config:

ts
layers: [
  { name: 'app',      patterns: ['src/app/**'] },
  { name: 'pages',    patterns: ['src/pages/**'] },
  { name: 'widgets',  patterns: ['src/widgets/**'] },
  { name: 'features', patterns: ['src/features/**'] },
  { name: 'entities', patterns: ['src/entities/**'] },
  { name: 'shared',   patterns: ['src/shared/**'] },
]

Порядок важен. Ранние слои могут импортировать поздние, никогда наоборот. Это всё правило. Никакой дополнительной конфигурации, никаких per-pair allowlists.

Если путь модуля матчит несколько паттернов, выигрывает первый. Модули, не подошедшие ни под один — unlayered, в layer-проверках не участвуют.

Нарушение слоя

Layer violation — импорт из более позднего слоя в более ранний. Пример: src/shared/lib/foo.ts импортирует из src/features/bar/index.ts — это нарушение, потому что shared не должен знать о features.

Каждое нарушение — одно ребро: from, to, fromLayer, toLayer. Они появляются:

  • В Insights десктопа.
  • Как <testcase failure> в JUnit-отчётах.
  • В --fail-on layer-violations:N CI-гейтах.

Layer-aware рекомендации

Кроме сырого подсчёта нарушений Archora добавляет два layer-aware инсайта:

  • misplaced-by-layer — путь модуля кладёт его в слой X, но ≥ 70% его dependents живут в одном другом слое Y. Перенос его туда уберёт много cross-layer шума.
  • top-violator — один модуль — источник непропорционально большого числа нарушений. Часто самый дешёвый single-file фикс на весь скан.

Без конфига слоёв

Без layers в конфиге проверка слоёв молча отключена — никаких нарушений, никаких layer-рекомендаций. Это намеренно: layered architecture — мнение, и мы не хотим выдумывать правила, о которых вас не просили.

Ограничения

  • Принадлежность слою — только по пути. *.vue файл в src/shared/ui/ считается shared независимо от того, что его <script> импортирует из features. Мы никогда не будем выводить «это вообще-то widget» из формы кода.
  • Правило «может импортировать» — однонаправленное. Если нужны двунаправленные правила (например, «entities и shared не могут импортировать друг друга») — пришлось бы держать их в двух same-rank слоях, что сейчас не поддерживается. Открывайте issue, если такое нужно.

См. также

Выпущено под лицензией BUSL-1.1.