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

Модификации FEOD ​

FEOD — это гибкая методология, которую можно адаптировать под конкретные нужды проекта. В этом разделе мы рассмотрим различные модификации и варианты применения FEOD, которые могут быть полезны в разных контекстах.

Базовые модификации ​

Здесь рассмотрим базовые модификации, которые меняют основную структуру FEOD и позволяют точнее адаптировать ее под конкретные нужды проекта.

Commonless FEOD ​

Базовая вариация FEOD без использования common-уровня. Это осуществляется путем переноса сущностей из Common в Modules. Что это дает?

  • Больше не нужно мучиться, пытаясь понять, когда common должен стать модулем
  • Меньше работы, связанной с отделением common от бизнес-логики
  • Элементы проще связывать между собой, так как теперь можно не переживать о запрете импорта модуля в common

Минусы у подхода также имеются:

  • Значительно раздувается список модулей
  • Связи между модулями станут более запутанными, так как связанность увеличивается

Если у вас проект небольшой, этот вариант может оказаться более предпочтительным, так как он позволяет избежать сложности с разграничением common и модулей. Однако с ростом проекта список модулей может стать слишком большим и запутанным. Это одна из причин, почему common важен в базовой вариации FEOD. Кроме того, модули могут стать сильно связанными, так как больше нет нужды в четком обдумывании связей. Common был выделен не просто так, и одна из его целей — дисциплинировать создание новых сущностей и сдерживать рост количества связей на проекте.

Рекомендации при использовании Commonless FEOD:

  • Старайтесь создавать новые сущности как подмодули, а не сразу помещать в самостоятельные модули
  • Группируйте сущности по смыслу, например, базовые UI-блоки можно группировать в модуль ui
  • Не создавайте псевдо-common-модули, такие как utilities, types, constants и т.д. Вместо этого выполняйте группировку по смыслу: date.ts / string.ts
  • А если хочется все-таки сделать что-то уровня common/types?
    • Пожалуй, это единственное исключение из правила, но только для Utility Types
    • Например, для типов вроде Flatten<Array> / Either<T> и т.п. Тут это имя продиктовано назначением типов.
    • Типы с бизнес-логикой лучше оставить в соответствующем модуле: type User / Product и т.п.

Common Module ​

Схожа с Commonless FEOD, но common-уровень целиком становится модулем. Это гибридный подход, и у него есть свои плюсы и минусы.

Достоинства относительно Commonless FEOD:

  • Так как в модулях есть требование публичного API, то можно объединять сущности в один импорт вместо отдельных
  • Нет каши на верхнем уровне, так как common-уровень целиком становится одним модулем

Недостатки:

  • Модуль имеет нечеткое определение с точки зрения назначения и не обладает самодостаточностью (так как он может импортировать другие модули)
  • Частое изменение публичного API модуля common
  • Элементы из него выносить менее комфортно, так как модуль имеет право импортировать другие модули

Рекомендации при использовании Common Module:

  • Старайтесь минимально использовать другие модули в common-модуле
    • Например, уместно для использования информации об авторизации пользователя, но не полноценное взаимодействие с пользователем
  • Старайтесь придерживаться всех правил FEOD относительно common-уровня, кроме особенностей импорта сущностей из других модулей
    • Используйте публичное API в index.js
    • Не импортируйте сущности из других модулей в common-модуль

Что насчет прозрачного модуля для common?

Достоинства:

  • Вместо одного импорта из common-модуля импорты будут разбиты на несколько по типу, и это даст более говорящее название
    • import { Card, chunks } from '@modules/common' =>
      • import { Card } from '@modules/common/ui'
      • import { chunks } from '@modules/common/utilities'

Направленные модификации ​

Эти модификации не меняют основную структуру FEOD, но подстраваются под некоторые потребности или особенности фреймворков.

Mutliapp ​

Эта модификация подходит, когда имея единый набор модулей или даже страниц вам нужно собирать различные приложения из них. Базовой вариацией может быть кастомный SSR, где по своей фронтовое и серверное приложение будут отдельными.

Базовая идея заключается в том, что app слой становится apps слоем.

По сути у нас появляется возможность собирать разные приложения из одного набора модулей или страниц. При этом у каждого приложения могут быть свои приватные модули и страницы. Однако при необходимости они легко могут перемещаться на верхние уровни и становиться общими для всех приложений.

На самом деле может быть уместна и попытка реализовать «глупые» приложения. В этом случае всё сводится к максимально тонкому app-уровню, в котором происходит только финальная донастройка приложения и запуск. Этот вариант может подойти, если вам нужно создавать множество крайне схожих приложений из одного набора модулей и страниц.

Собственные слои ​

Набор слоёв и разрешённые связи между ними задаются конфигурацией (layers), а не зашиты в правила. Вместо цепочки возможен и граф: в backend-наборе routes и middlewares стоят над modules параллельно и не импортируют друг друга. Свой слой можно добавить к готовому набору обычным spread.

Добавляйте слой, когда в графе есть узел с явной ролью, который иначе приходится держать в modules ради обхода правил. Помните, что каждый слой это ещё одно решение «куда положить», а гарантии при этом становятся локальными: в двух проектах слово «слой» может значить разное. Подробнее в конфигурации FEOD.