BetaДокументация для beta‑теста, возможны ошибки и неточности.
Перейти к содержимому

feod-structure/layer-imports ​

Направления зависимостей и публичные API модулей.

Включено как error в recommended и strict. Autofix отсутствует. Поддерживается ESLint и Oxlint.

Зачем нужно ​

Не даёт слоям зависеть от запрещённых слоёв и закрывает приватную реализацию модулей. Это основная проверка архитектурных границ: алиас не позволяет обойти публичный API.

Что проверяет ​

Для стандартного набора разрешены следующие направления:

ИсточникДопустимые цели
appapp, pages, modules, common
pagesmodules, common
modulesmodules, common
commoncommon
globalВсе стандартные слои

Остальные слои не могут импортировать global. Слой app может импортировать собственные файлы; страницы по умолчанию изолированы друг от друга. Для пользовательских наборов направления определяются layers.*.imports.

Внешний потребитель модуля должен использовать публичный entry (index.* по умолчанию) или импорт каталога. Внутри собственного модуля допустимы импорты реализации. По умолчанию родитель обращается к ребёнку через API, ребёнок может читать реализацию непосредственного родителя. Между корнями нужны dependencies и публичный API верхнего модуля целевого корня.

Примеры ​

Ошибка ​

ts
// src/common/format.ts
import { user } from '@modules/User'; // common не зависит от modules

// src/pages/profile.ts
import { model } from '@modules/User/model'; // приватный файл

Корректно ​

ts
// src/pages/profile.ts
import { user } from '@modules/User'; 
import { format } from '@common/format';

// src/modules/User/view.ts
import { model } from './model'; // собственная реализация

Посмотрите границу в файлах ​

Откройте profile.ts, затем User/index.ts и User/model.ts в дереве. На строках импорта отмечены ошибка и допустимый путь. Наведите на маркер или нажмите его, чтобы прочитать пояснение.

  • src
    • pages
    • modules
      • User

Выберите файл в дереве слева

Наличие публичного экспорта в index не разрешает прямой импорт model.ts. Потребитель использует API, а сам модуль свободно меняет внутреннюю структуру.

Исправление импорта ​

ts
// src/pages/profile.ts
import { userState } from '@modules/User/model'; 
import { userState } from '@modules/User'; 

Путь меняется на публичный API; внутренний файл модуля остаётся на своём месте.

Настройка ​

js
createConfig({
  singleFileModules: true,
  transitModules: ['package-manager'],
  modulePages: true,
  modules: { publicEntries: ['index.ts'] },
  submodules: {
    visibility: 'parent-only',
    parentImports: 'public',
    childImportsParent: 'implementation',
  },
  imports: { computed: 'forbid', unresolved: 'forbid' },
  globals: { localImports: 'type-only' },
});
Поле проектаПо умолчаниюПоведение
layersfrontendLayersСлои и разрешённые направления
dependencies у корня[]Разрешённые целевые корни
modules.publicEntries[]Пустой список сохраняет index.*, непустой задаёт точные имена
singleFileModulesfalseМодули вида modules/logger.ts
transitModules[]Прямые подмодули transit-контейнера; _ — приватное ядро
modulePagesfalseСтраницы modules/Name/pages, доступные из Name/index.*
submodules.visibility"public"parent-only закрывает API ребёнка от посторонних
submodules.parentImports"public"implementation разрешает родителю внутренние файлы ребёнка
submodules.childImportsParent"implementation"public требует API непосредственного родителя
imports.computed"ignore"forbid запрещает неизвестные выражения в import/require
imports.unresolved"ignore"forbid сообщает локальные пути без существующего файла
globals.localImports"allow"type-only или forbid для исходящих локальных импортов globals

Прямые options принимают группы пути, алиасы, layerDirs, layers, dependencies, submodules, imports, globals, transitModules, singleFileModules, modulePages и publicEntries. Поле modules в options правила не передаётся.

Ограничения и связанные правила ​

Поддерживаемые формы зависимостей перечислены во введении. Type-only импорты также соблюдают границы. globals.localImports: 'type-only' не отменяет остальные ограничения для разрешённых типов.

Существование публичного entry проверяет module-entries. Циклы проверяют no-module-cycles и no-file-cycles. Дополнительные ограничения вложенных модулей задаёт no-submodule-of-submodule. Пути, не отнесённые к слоям, и исключения ignore могут оставлять границы непроверенными; используйте no-unknown-files.

Реализация ​

Исходный код · Тесты · Все правила