Введение в FEOD
Это полное введение в FEOD. Здесь вы найдете основные концепции и принципы, которые лежат в основе методологии. Если вы хотите быстро разобраться в методологии, то можете ознакомиться с кратким введением. Здесь же попытка дать полноценное обоснование и стиль мышления заложенный в основе FEOD.
FEOD (Fractal Entity Oriented Design) — это методология организации структуры фронтенд-приложений, которая сочетает в себе слоистый и модульный подходы. Она разработана для решения проблем современной фронтенд-разработки, однако может быть использована для разработки библиотек, BFF и прочих типов проектов.
Важным моментом для FEOD является то, что он не является строгим и не навязывает вам какую-то конкретную архитектуру. У нее очень богатая вариантивность и если вам кажется, что что-то должно быть иначе, то скорее всего вы можете это сделать и под это будут опции. Тут могут возникнуть сомнения: в чем смысл если я могу сделать что угодно и у меня мало ограничений? FEOD дает возможность описать вашу вариацию и далее строго следить за ее соблюдением. При этом все вариации достаточно близки по духу и стилю мышления.
Важный момент который хочется заранее обозначить: в первую очередь FEOD это попытка найти разумное описание модульной архитектуре и дать ей докуметацию и полноценный туллинг. Если вы уже используете нечто похожее на модульную архитектуру, то FEOD может показаться вам знакомым и одна из его возможных вариаций опишет ваш подход. Таким образом вы сможете получить документацию и для своего подхода, а также получить возможность использовать инструменты для работы с FEOD и в вашем случае. Чтобы подробнее узнать о вариативности FEOD вы можете ознакомиться с модификациями.
Кроме того важная задача FEOD это дать понимание, как правильно строить архитектуру проекта и как её правильно использовать. Дать советы как правильно использовать модули и как они должны взаимодействовать между собой для получения желаемого результата.
Таким образом FEOD это не просто методология сама о себе, а попытка комплексного осмысления модульной архитектуры и дать ей полноценную документацию и туллинг.
Архитектура vs. Структура. Почему это важно?
Первое, на чём стоит остановиться — это различие между архитектурой и структурой проекта. Эти понятия часто путают, хотя на деле они отвечают на разные вопросы.
Структура — это про то, где что лежит. Файлы, папки, модули — насколько они удобно организованы, легко ли найти нужное место в проекте, внести изменения, добавить новую функциональность.
Архитектура же касается логики — какие элементы взаимодействуют между собой и по каким принципам. Это уровень связей и правил, которые обеспечивают работу приложения.
Структура и архитектура не тождественны, но одна без другой работает плохо. Если в проекте хаос и файлы раскиданы где попало, то и продуманную архитектуру построить будет крайне сложно. Поэтому структура становится фундаментом для грамотной архитектуры. Можно сказать так: структура отвечает за организацию кода, а архитектура — за организацию логики.
Когда мы говорим о структуре и архитектуре, может показаться, что это сугубо технические детали, которые нужны только разработчикам. Но на самом деле правильная организация кода оказывает прямое влияние и на команду, и на бизнес.
Для команды это, в первую очередь, единый язык общения. Когда в разных проектах принципы организации одинаковые, новички быстрее включаются в работу. Переход с одного проекта на другой не превращается в стресс — разработчику не приходится тратить дни на то, чтобы понять, где что лежит и как это принято именно здесь. Вместо этого он открывает знакомую структуру и сразу чувствует себя «дома».
Кроме того, наличие четких правил снимает множество спорных моментов. В документации всегда можно найти ответ на вопрос «а как правильно», и тогда код-ревью превращается не в столкновение субъективных мнений, а в процесс, где есть понятные ориентиры. Это снижает количество конфликтов, ускоряет работу и делает ее прозрачной.
Если смотреть шире — с точки зрения бизнеса — эффекты еще заметнее. Унифицированная структура позволяет безболезненно перемещать сотрудников между проектами: человек приходит на новый продукт и практически сразу включается в задачу, потому что всё организовано по тем же принципам. То же самое касается и запуска новых проектов: не нужно каждый раз изобретать велосипед, тратить время на обсуждения базовых вещей — есть готовый проверенный подход, который можно просто взять и применить.
Наконец, важный момент — масштабирование. Когда проект вырастает, поддерживать его становится все сложнее и дороже. Но если структура была продумана заранее, это «разрастание» не превращается в хаос. Добавление новых модулей и фич идет предсказуемо, а стоимость поддержки остается управляемой.
В итоге мы получаем не только аккуратный код, но и предсказуемость: в скорости, в качестве, в стоимости разработки. Это то, что одинаково важно и инженерам, и менеджерам, и всей компании в целом.
Чем же является FEOD? Это также как и FSD — методология для организации структуры проекта, но с альтернативным подходом. Используя FEOD вы получаете структуру которая отчасти навязывает некоторую архитектуру, однако она все еще остается за вами.
Можно ли сказать что FEOD это структура проекта? Не совсем, так как в FEOD заложена вариантивность и выражение FEOD-структура может дать слишком мало в понимании. Но вы можете сказать что FEOD это методология по которой был построен и является соместимым с туллингом созданным для FEOD.
Проблематика современных проектов
Разработка современных фронтенд-приложений требует качественной структуры проекта, на которую удобно опираться при разработке архитектуры самого приложения. Существующие решения либо не дают ответов на вопросы, либо являются слишком примитивными для сложных проектов. Бывают и обратные случаи, когда построение архитектуры настолько переусложняется, что создаёт больше проблем, чем пользы, порождая бесконечные споры.
Когда мы говорим о структуре фронтенд-приложений, то сразу встаёт вопрос: как вообще всё это организовать? На практике нередко получается каша из компонентов и логики. Сначала создаёшь какой-то кусочек, он требует соединения с другим, потом кладёшь его в одно место, ещё часть — в другое, и в итоге уже непонятно, что где лежит и как всё это искать.
Отдельная боль — циклические импорты и контроль связей между модулями. Если проект строится на модульной архитектуре, очень быстро всплывает проблема: модули знают слишком много друг о друге. Получается не структура, а очередная каша, только уже из связей.
Плоские структуры проектов приводят к смешиванию различных сущностей и потере контроля над структурой, в то время как слишком сложные архитектуры требуют значительных временных затрат на изучение и соблюдение множества правил. FEOD стремится найти баланс между этими крайностями.
Основные концепции FEOD
FEOD базируется на трёх ключевых концепциях, каждая из которых решает конкретные проблемы современной фронтенд-разработки.
Модульность
Модуль — это независимая часть проекта, которая имеет свою структуру, правила и поведение. Каждый модуль можно рассматривать как микро-зависимость в коде. Модули могут иметь свои подмодули (модули внутри модуля), а также обращаться к другим модулям через чётко определённые интерфейсы.
Модули это центральная идея для FEOD и по факту все остальное это лишь инструменты для её реализации. Поэтому важно уделить им особое внимание. Подробности о модуляхх вы можете найти в документации по структуре.
Почему модульность?
Проблема, которую решает модульность, — это каша из компонентов и логики, о которой мы говорили выше. Когда код организован в модули:
- Изоляция функциональности — каждый модуль инкапсулирует свою логику, что предотвращает смешивание различных сущностей
- Чёткие границы ответственности — сразу понятно, за что отвечает модуль и где искать связанный код
- Упрощение тестирования — модуль можно тестировать изолированно, не поднимая всё приложение
- Улучшение поддерживаемости — изменения в одном модуле минимально затрагивают другие, если границы соблюдены
- Контроль связанности — модули взаимодействуют через явные интерфейсы, что уменьшает вероятность циклических импортов и неопределённых зависимостей
- Контроль ответственности — модули могут иметь конкретных ответственных за них разработчиков
- Документирование — модули могут иметь документацию, что помогает разработчикам быстрее понять, как использовать модуль, а AI-агентам — его назначение и поведение
Модульность также позволяет выносить модули в самостоятельные пакеты при необходимости, что особенно важно для микрофронтендов и монорепозиториев.
Фрактальность
Фрактальность — это способ организации кода, который позволяет создавать вложенные структуры без ограничения глубины. В FEOD фрактальность — это свойство модулей, позволяющее создавать модули внутри модулей для любой необходимой глубины.
Если вас пугает возможность слишком глубоких вложений, то не переживайте. Каждое вложение должно быть обоснованным и более трех уровней вложения крайне не рекомендуется.
Почему фрактальность?
Проблема, которую решает фрактальность, — это ограничения плоских структур и раздутость отдельных уровней.
- Естественное масштабирование — когда модуль становится слишком большим, его можно разбить на подмодули, не нарушая общую структуру проекта
- Отсутствие искусственных ограничений — не нужно придумывать новые горизонтальные срезы или уровни, когда функциональность растёт
- Сохранение принципов — подмодули следуют тем же правилам, что и модули верхнего уровня, что снижает когнитивную нагрузку
- Гибкость организации — можно создавать структуру любой глубины, соответствующую реальной сложности функциональности
Фрактальность позволяет проекту расти органично, без необходимости кардинальной перестройки архитектуры при добавлении новых фич.
Сущность-ориентированность
Каждый файл или директория в проекте рассматривается как сущность с определённой ролью. Это помогает быстро понять назначение и ограничения каждой части проекта.
Сущность — это любой файл или директория в проекте, имеющий свою роль (не путать с понятием «сущность» в контексте DDD). Это не какой-то особый термин, а просто унифицированный способ сказать "эта штука" в рамках файловой системы проекта.
- Сущности для проекта — это как типизация для файлов и директорий, позволяющая чётко ограничить возможные наименования и правила для конкретной сущности
- Тип сущности полностью определяет её поведение — позволяет быстро во время ревью определить, что к чему, и ограничить возможность потенциальных ошибок
- Тип сущности не является специальным словом, а лишь совокупностью для связи наименований: имя, правила, выполняемые функции
- Эти правила для сущностей позволяют проектам оставаться в одном стиле и с примерно консистентными наименованиями, которыми также можно оперировать при обсуждении
Почему сущность-ориентированность?
Проблема, которую решает сущность-ориентированность, — это потеря контроля над структурой и неопределённость в организации кода.
- Быстрое понимание назначения — по имени и расположению сущности сразу понятно, что она делает и какие правила к ней применяются (модуль / страница / компонент / и т.д.)
- Предотвращение ошибок — чёткие правила для каждой сущности ограничивают возможность неправильного использования
- Единообразие — все проекты, следующие FEOD, имеют одинаковую структуру и наименования, что упрощает переход между проектами
- Упрощение код-ревью — ревьюер сразу понимает, соответствует ли код правилам для данной сущности
- Автоматизация — можно создавать инструменты, которые проверяют соответствие структуры правилам FEOD
Сущность-ориентированность даёт чёткое понимание в наименованиях, что где будет находиться, что критически важно для скорости вхождения новых разработчиков в проект.
Уровни
Уровень — это понятие для описания всех вложенных сущностей в другую сущность. Например, уровень modules — у него все вложенные сущности — это модули и ничто иное.
Тут опять же особого термина нет, это просто принятое определение для обозначения местоположения "сущностей" в файловой системе. Например, уровень modules — у него все вложенные сущности — это модули. Также могут быть уровни pages, common, global и другие.
Уровни являются связующим звеном между фракталами и сущностями. Обычно доступ между уровнями обеспечивается правилами уровня: кто и откуда имеет к этому доступ.
Главные уровни (слои) сущностей в FEOD:
- Global сущности нигде не импортируются, так как там объявляются и расширяются глобальные сущности
- Common сущности могут импортироваться из modules, pages и app
- Modules сущности могут импортировать common и другие modules (только через публичный API,
index.ts) - Pages сущности импортируются только из app и могут импортировать common и modules
- App может импортировать common, modules и pages
- App не импортируется никем и является входной точкой в приложение
Итого цепочка: common ➜ modules ➜ pages ➜ app | Global — не импортируется никуда
Эти правила обеспечивают чёткий контроль над связанностью между сущностями и лёгкий контроль над импортами и экспортами, что было одной из целей методологии.
Описание верхних уровней
App — входная точка приложения, содержащая всё необходимое для запуска и настройки. Здесь находятся конфигурации, роутер, интеграции с внешними сервисами, основные лейауты и точка входа.
Pages — страницы приложения, соответствующие URL-маршрутам. Структура файлов напрямую отражает структуру URL, что делает навигацию интуитивной. Страницы значительно изолированы от бизнес-логики и используют модули для её реализации.
Modules — логика приложения, организованная в независимые модули. Каждый модуль инкапсулирует функциональность и может содержать подмодули (фрактальность). Модули могут взаимодействовать друг с другом, но должны быть максимально изолированы.
Common — общие переиспользуемые сущности, не привязанные к конкретной бизнес-логике. Включает UI-компоненты, композаблы, утилиты, типы и сторы общего назначения. Может импортироваться откуда угодно.
Global — глобальные определения, доступные без импорта. Используется для полифиллов, расширений интерфейсов, глобальных типов и shim-ов библиотек.
Далее вы сможете ознакомиться подробнее с каждым из уровней и их правилами.
Осмысление FEOD
Структура проекта должна обеспечивать не только простоту и понятность, но и гибкость и возможность расширения. Однако важно также обеспечить метрики по скорости вхождения разработчиков в проект. Для этого нужно обеспечить простой и понятный поток мысли. И многие решения о структуре проекта были предприняты именно для этого.
Представим себя на месте нового человека на проекте. Ему для начала работы нужно разобраться, с чем вообще предстоит ему работать, и структура должна этому способствовать. Смоделируем эту ситуацию:
- Видит app и понимает, что это входная точка приложения. По ней он может примерно понять, что подключено к проекту, какие есть интеграции и т.д.
- Видит pages и понимает, что это страницы приложения. По ней он может понять, что есть и какие есть страницы и кто за них отвечает.
- Видит modules и может примерно оценить, на какие логические блоки разбит проект. Далее каждый модуль изучается планомерно по отдельности, не отвлекаясь на внешние сущности.
- Видит common, и этот уровень несёт в себе не так много смысловой нагрузки — просто сущности, которые могут быть использованы везде.
- Видит global, там он всегда может знать, что ему доступно без импортов и куда это положить.
Таким образом, структура проекта позволяет быстро понять, что есть и как это работает. Мы не отвечаем на вопрос "сколько есть компонентов", "сколько есть страниц", "сколько есть модулей" и т.д. Мы отвечаем на вопрос "как это работает" и "что где искать".
Также такая структура не создаёт ментального перенапряжения, которое возникает со структурами, в которых процесс определения уровня сущности занимает важное место (как, например, в FSD). Но при этом можно не переживать, как при плоской структуре, когда сущности пытаются смешаться между собой (например, компонент и несколько файлов, связанных с ним логики).
Также структура должна быть лёгкой для того, чтобы переехать на неё. Если начинать с плоской структуры, то вам нужно будет сначала выделить app, далее постепенно перетаскивая сущности в модули.
Гибкость во главе
Отдельно хочется отметить гибкость как важную ценность FEOD. Это нормально перемещать файлы между уровнями по мере разработки проекта. Элементы в common могут переместиться в моменте в modules или некая сущность из модуля может понадобиться где-то еще и она может как стать отдельным модулем или даже уйти в common. Таким образом не так страшно поместить что-то не туда, так как это можно будет легко исправить в будущем.
Базовая структура проекта
Важно
FEOD не навязывает правил наименования сущностей, а сосредоточен на определении ролей и их связях. Это позволяет адаптировать проект под конкретные привычки. В примерах ниже вы можете использовать любое удобное вам наименование и ознакомиться с допустимыми модификациями.
Базовая структура проекта (Vue + SPA)
Это лишь пример реализации структуры, вы вольны менять названия и вложенности на свое усмотрение. Главное, чтобы сохранялись правила FEOD.
Сравнение с другими подходами
FEOD не является серебряной пулей. Также в ней заложена определенная вариативность и вы можете адаптировать ее под ваши нужды. Мы постарались объединить сильные стороны других подходов и минимизировать слабые стороны. Конечно же, тут все еще упирается в определенные компромисы.
Основные отличия
FEOD vs FSD (Feature-Sliced Design)
Важно
FEOD не является вариацией FSD, а является полностью отдельной методологией. С отличной философией и подходом к организации проекта. Хотя определенные сходства все-таки есть.
- FEOD использует упрощённую структуру (5 уровней против 7 в FSD)
- Модули FEOD заменяют уровни features, widgets и entities из FSD. Хотя есть отличия и в схожих слоях
- FOED делает важный акцент на понятии модуля и работу с модулями. Тогда как FSD фокусируется на слоях асбтракции и их взаимодействии.
- Поддержка фрактальности без ограничения глубины
- Меньше когнитивной нагрузки при принятии решений
- FEOD не такой строгий как FSD, поэтому вероятность циклических зависимостей все-таки выше
Важно
Термин «слой» который вам мог быть знаком в том числе из FSD, далее можно считать синонимом «уровня» для верхних уровней структуры.
Верно и обратное: термин «уровень» является синонимом «слоя» в большинстве случаев.
FEOD vs Atomic Design
- FEOD фокусируется не только на компонентах, но и на бизнес-логике
- Чёткое разделение бизнес-логики (в модулях) и представления (в компонентах)
- Atomic сам по себе дает очень мало ответов на вопросы о структуре проекта и его организации.
FEOD vs Модульная архитектура
- FEOD и есть вариация модульной архитектуры, но четко задокументированная
- FEOD добавляет уровни app, pages и globals для более чёткой организации
- Описанные строгие правила импорта между уровнями
FEOD vs Плоская архитектура
- Группировка по функциональности и роли, а не по типу
- Лучшая масштабируемость благодаря модульности
- Обеспечивает лучшую изоляцию через модули со всеми вытекающими из этого преимуществами
Расширения для продвинутых проектов
FEOD поддерживает несколько расширений, которые открывают путь к более сложным и продвинутым сценариям использования.
SSR (Server-Side Rendering)
FEOD изначально спроектирован так, чтобы поддерживать SSR. Для работы с ним достаточно вынести отдельный уровень Server с точками входа:
entry.server.ts— точка входа сервераentry.client.ts— точка входа клиента
Либо выберите в выпадающем списке вариант для вашего фреймворка.
IoC (Inversion of Control)
В FEOD акцент сделан на отказ от кросс-модульных взаимодействий в пользу Dependency Injection. Это делает зависимости явными и управляемыми, что особенно важно при росте проекта.
Интеграция с DDD (Domain-Driven Design)
Если в вашей команде много бэкенд-разработчиков и они привыкли мыслить в терминах DDD, FEOD легко подстраивается под этот подход. В модулях можно выделить дополнительные сущности — Entities и Adapters.
Использование за пределами фронтенд-приложений
FEOD может применяться не только в frontend-приложениях, но и в:
- UI-библиотеках
- Инструментах разработки (линтеры, плагины, утилиты)
- Монорепозиториях
- Микрофронтендах
Модификации
FEOD — это гибкая методология, которую можно адаптировать под конкретные нужды проекта. Существуют различные модификации и варианты применения FEOD, которые могут быть полезны в разных контекстах.