Как строил архитектуру до Feature-Sliced Design?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Эволюция архитектуры до Feature-Sliced Design
До появления Feature-Sliced Design (FSD) архитектура фронтенд-приложений проходила несколько ключевых этапов, каждый из которых был реакцией на растущую сложность проектов. Вот как я выстраивал архитектуру в те годы.
Монолитная структура по типам файлов (по технологии)
В начале 2010-х доминировал подход группировки файлов по их технологической принадлежности — классическая структура, унаследованная от бэкенда.
project/
├── css/
│ ├── main.css
│ └── reset.css
├── js/
│ ├── utils.js
│ ├── components.js
│ └── app.js
├── images/
└── index.html
- Проблемы: При росте проекта папки
css/иjs/превращались в "свалку". Поиск кода, связанного с одной фичей (например, "корзины покупок"), требовал рысканья по всем директориям. Связность кода была низкой, а зацепление — высоким.
Подход с компонентами (с появлением React/Vue)
С приходом React и идеологии "компонентов" структура улучшилась, но часто оставалась плоской или слабо организованной.
src/
├── components/ # Все компоненты в одной куче
│ ├── Button.jsx
│ ├── Header.jsx
│ ├── ProductCard.jsx
│ └── ShoppingCart.jsx
├── containers/ # "Умные" компоненты
├── redux/ # Вся логика хранилища в одном месте
│ ├── actions.js
│ ├── reducer.js
│ └── store.js
├── utils/ # Общие утилиты
└── App.js
- Недостатки: Директория
components/быстро раздувалась до сотен файлов. Компоненты, связанные с одной бизнес-логикой, были разбросаны. Redux-сторе становился "божественным объектом", куда сваливались экшены и редьюсеры со всего приложения. Тестирование и рефакторинг усложнялись.
Группировка по фичам (Feature-Based Folders)
Следующим логическим шагом стала группировка по бизнес-доменам или фичам — ранний прообраз FSD.
src/
├── cart/ # Фича "Корзина"
│ ├── components/
│ │ ├── CartItem.jsx
│ │ └── CartSummary.jsx
│ ├── redux/
│ │ ├── actions.js
│ │ └── reducer.js
│ └── index.js # Публичный API фичи
├── product/ # Фича "Продукт"
│ ├── components/
│ ├── redux/
│ └── api/
├── shared/ # Переиспользуемые ресурсы
│ ├── ui/
│ └── lib/
└── App.js
Это был значительный прогресс. Принцип инкапсуляции работал лучше: код фичи находился в одном месте. Однако возникали новые вопросы:
- Где хранить общие компоненты (
Button,Modal)? Вshared/ui? А если они используются только в 2-3 фичах? - Как быть с кодом, который не относится к фиче, но нужен многим (например,
formatDate)? Он попадал вshared/lib, которая со временем становилась "мусорным ведром". - Отсутствовали четкие правила взаимодействия между слоями. Фича
cartмогла импортировать что угодно изproduct, создавая скрытые зависимости.
Внедрение концепции "Слоев" (Layers)
Чтобы навести порядок в зависимостях, я начал явно разделять код по типу ответственности (слоям), часто вдохновляясь Clean Architecture и DDD.
// Пример слоистой структуры внутри фичи
src/features/cart/
├── model/ # Бизнес-логика, хранилище (Redux slice/MobX store)
├── ui/ # Компоненты, специфичные для этой фичи
├── lib/ # Вспомогательная логика фичи
└── api/ // Запросы к бэкенду, специфичные для корзины
Ключевое правило: Допустимы только нисходящие зависимости (например, ui может зависеть от model, но не наоборот). Это повышало тестируемость (бизнес-логику можно тестировать изолированно) и переиспользуемость.
Проблемы, которые оставались до FSD
Несмотря на все улучшения, несколько системных проблем сохранялись:
- Непоследовательность (Inconsistency): В каждом новом проекте или команде эти "лучшие практики" интерпретировались по-разному. Не было единого стандарта.
- Сложность масштабирования: При добавлении новых типов сущностей (например,
hooks,constants) не было очевидно, куда их поместить. - "Провал" общих ресурсов: Слой
shared/илиcommon/становился точкой хаотичного связывания удаленных частей приложения. - Слабые границы модулей: Запрет на циклические зависимости и контроль направления импортов требовал ручного код-ревью и дисциплины, а не был встроен в архитектуру.
Итог и переход к FSD
Таким образом, эволюция шла от технологической группировки к бизнес-ориентированной, а затем к слоистой внутри бизнес-логики. Мы интуитивно стремились к высокий связности (cohesion) внутри модулей и низкому зацеплению (coupling) между ними.
Feature-Sliced Design стал закономерным и долгожданным итогом этого пути. Он систематизировал все эти наработки в единую, хорошо документированную методологию с:
- Четкими слоями (
app,processes,pages,features,entities,shared), определяющими уровень ответственности. - Жесткими правилами зависимостей (сверху вниз).
- Сегментацией (
slices) внутриfeaturesиentities, что окончательно решало проблему "раздутых" папок. - Публичным API каждого модуля для контроля инкапсуляции.
Опыт построения архитектуры "до FSD" бесценен — он позволяет по-настоящему оценить, какие боли решает эта методология, и осмысленно применять её принципы, а не слепо следовать правилам.