Архитектура фронтенд-приложений

Недавно осознал, что архитектура которая у нас выстраивалась годами - это почти Feature-Sliced Design. Просто я об этом не знал.

Я хочу поделиться тем, к каким правилам и ограничениям мы пришли в своих проектах спустя годы написаний приложений с нуля.

Для примера возьму два модуля - users и tasks. В какой-то момент стало понятно: удобно когда всё что касается одной сущности лежит рядом и не пересекается с другими. Так появились правила - сторы из папки tasks не лезет в сторы users, компоненты users тянет только свои сторы. Так же компоненты users ничего не знают про tasks, и наоборот.

Структура получилась такая: views → components → stores → services → api

Внутри каждого слоя - деление по сущностям: users, tasks, common (для глобальных вещей). Отдельно живут composables и helpers - они глобальные, но тоже с разделением на общие и привязанные к сущности. Через них переиспользуется логика между слоями без нарушения границ.

Когда прочитал про Feature-Sliced Design - удивился. Принципы те же: изоляция, явные границы, предсказуемые зависимости. Нет features и widgets как в классическом FSD, но мышление совпадает.

Для наглядности вот как примерно выглядела бы моя структура папок: src/ ├── views/ │ ├── UsersView.vue │ ├── TasksView.vue │ └── LoginView.vue ├── components/ │ ├── users/ │ ├── tasks/ │ └── login/ ├── stores/ │ ├── common/ │ ├── tasks/ │ ├── login/ │ └── users/ ├── services/ │ ├── users/ │ ├── tasks/ │ └── login/ ├── api/ │ ├── users/ │ ├── tasks/ │ └── login/ ├── composables/ │ ├── common/ │ └── users/ ├── helpers/ └── types/

Главное отличие: у меня слои горизонтальные, а сущности внутри. В FSD наоборот - сущности и фичи наверху, а ui/api/lib внутри каждой из них.

Такой подход хорошо работает на средних проектах - когда приложение уже достаточно большое чтобы нужна была структура, но ещё не настолько сложное чтобы оправдать полный FSD. Легко объяснить новому человеку в команде, легко расширять - просто добавляешь новую папку сущности на каждом слое. Если проект вырастет до десятков фич с общей логикой между ними - скорее всего придётся двигаться в сторону классического FSD. Но до этого момента усложнять не стоит.