Методология "feature-sliced" - идеальный способ структурировать растущий проект?

Олег Кусов21.09.2021
Архитектура
Фронтенд
Методологии
Feature-sliced

React-приложения отличаются тем, что не имеют какой-либо стандартной архитектуры. Почти каждое frontend-приложение на React имеет свою уникальную файловую архитектуру. Это приводит к тому, что, когда на проекте появляются новые ребята, им приходится довольно долго вливаться в проект. Мне, например, потребовалось несколько недель, чтобы вникнуть в кодовую базу своего проекта. Как же можно ускорить этот процесс и сэкономить деньги бизнеса и упростить в целом вовлечение разработчиков?

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

Нельзя сказать, что вместе с feature-sliced архитектурой сама разработка станет быстрее, потому что в проекте появляется довольно сильное разделение кода и сам процесс разделения может быть не быстрым. И не потому что сложно создавать папки и файлы, а потому что сложно решать что является чем.

А если конкретнее, методология состоит из разделения на страницы, виджеты, фичи, сущности и shared-компоненты. В папке каждой сущности, виджета, страницы происходит разделение на /ui, /lib, /model. Основная сложность при использовании методологии заключается в том, чтобы грамотно разбить код. Всегда проще просто взять, вынести компоненты фичи в папку /components, но со временем - с ростом проекта - приходит понимание того, что не всё так просто, и длинная папка /components может не радовать, как и размазывание логики фичи по множеству папок, будь то /redux или какая-нибудь /core папка, куда складываются бизнес-сущности и их логика.

Что является фичей?

Методология постоянно улучшается, и до внедрения виджетов фичи могли представлять собой довольно крупные куски кода, например, попап добавления пользователя. Сейчас же с появлением виджетов мы можем сказать, что попап добавления юзера является виджетом, а вот кнопка, которая отвечает за добавление - это фича. Инпуты для ввода имени и других данных юзера - это shared-компоненты. Если же в попапе используется какая-либо уникальная функциональность, помимо кнопки добавления юзера, её тоже стоит вынести в папку фич.

Сущность, фича или виджет?

Таким образом, виджеты - это крупные компоненты, которые включают в себя несколько действий и представляют собой цельную сущность. Представим, что у нас есть сущность user. В папке entities/user мы точно можем хранить типы сущности, в entities/user/ui, например, можно хранить карточку пользователя. В user/model будет храниться вся бизнес-логика, связанная с сущностью пользователя. Но что именно? Здесь возникают вопросы. Мы можем хранить здесь эффект получения данных юзера, можем хранить какое-либо действие, связанное с юзером. И в то же время, эффекты могут быть частью виджета, а различные действия, связанные с юзером, могут быть частью модели фичи. На мой взгляд, в этом вопросе нет четких правил и однозначно верного решения.

В теории карточка пользователя включает в себя shared-комопнент , который можно переиспользовать везде. Логичный вопрос - зачем нам user/ui/card, если UserCard является скорее оберткой над shared-компонентом Card? Ну компонент может и не быть shared, согласитесь. UI сущность может иметь уникальные компоненты, которые нигде не используются. Да, мы можем напрямую использовать shared-компонент Card в нашем виджете. И это вряд ли будет ошибкой, но в таком случае мы размажем логику, связанную с юзером, внутри более общей сущности - виджета. Думаю, лучше всё-таки стараться сильнее связывать код, который напрямую связан с Entity.

Представим, что в будущем нам может понадобиться по наведению на карточку показывать попап с подробной информацией о пользователе. Мы можем сделать эту функциональность частью виджета - так делать не желательно, нужно стараться не засорять виджет бизнес-логикой. Мы можем сделать эту функциональность частью фичи, а можем попросту вынести её в сущность user. На мой взгляд, оба возможны, и всё зависит лишь от ваших предпочтений. Грань между моделью сущности и моделью фичи для меня выглядит очень расплывчато.

Если вы не согласны с моим мнением, делитесь им в Telegram-чате по feature-sliced и не забывайте подписываться на меня в Twitter.