Сегодня никого не удивишь тем, что бизнес-требования и приоритеты в развитии проектов постоянно меняются. Поэтому важно спроектировать такую архитектуру, которая будет гибкой, легко масштабируемой и поддерживаемой, а также иметь единую терминологию. Это позволит онбордить новых сотрудников на проекте быстро и эффективно. Мы используем preact/compat — с его помощью получаем доступ к множеству библиотек экосистемы React, что делает разработку более гибкой, и при этом можем использовать Preact. Но эти же плюсы зачастую оборачиваются в обратную сторону: например, нет единой методологии по проектированию приложений, как, например, в Angular. Кроме того, многообразие библиотек усложняет погружение в проект, а свобода в реализации и проектировании может обернуться захламлением кодовой базы, что пугает разработчиков, особенно новичков.  Я встречал проекты, в которых раскиданы несколько одинаковых по функционалу компонентов. Например, пять вариаций одной кнопки, а чистые UI-компоненты находились рядом с компонентами, напрямую связанными с доменной областью приложения. Для нашей команды эти проблемы также актуальны. Чтобы их решить раз и навсегда, мы обратились к активно развивающейся методологии Feature-Sliced Design (FSD). Ниже я познакомлю с ее главными принципами и с нашим опытом ее использования. Забыл представиться — я Женя, фронтенд-разработчик в команде Quick Experiments inDrive. Расскажу, как мы занимаемся разработкой внутренних стартапов на основе бизнес-гипотез с помощью FSD. В методологии FSD используются три уровня абстракции:  1. Cлои. Этот уровень определяет скоуп ответственности слоя, а также уровень опасности изменений. Чем выше расположен слой, тем выше уровень его ответственности и знаний о других слоях. Чем ниже расположен слой, тем он более абстрактный и больше используется в верхних слоях, а значит больше опасности вносить в него изменения. 2. Cлайсы. Они отображают конкретную функциональность бизнес-логики. Методология почти не влияет на этот уровень, многое зависит от конкретного проекта. По факту это папки, которые группируют файлы, реализующие тот или иной модуль. 3. Сегменты. Распределяются по назначению модуля в коде и реализации. По методологии каждый сегмент отвечает за свою часть технической реализации модуля: api/ — работа с API. Авторы методологии советуют класть API-логику в shared, чтобы она не распылялась по проекту. config/ — конфигурация модуля. lib/ — различные утилитарные функции и вспомогательные библиотеки.  model/ — бизнес-логика: store, actions, effects, reducers и так далее. ui/ — отвечает за отображение.  Наша команда практически не использует третий уровень из-за того, что он усложняет структуру приложения. Было решено применять сегменты только в случае, если модуль будет достаточно большим и двух уровней декомпозиции не хватит для корректного абстрагирования логики. Важное правило архитектуры FSD, о котором я не могу не упомянуть: Один модуль не должен использовать другой модуль, расположенный на том же слое или на слоях выше. Например, фича А не должна импортировать фичу B. В противном случае модули перестают быть изолированными друг от друга и теряют устойчивость к новыми требованиям.  Когда мы модифицируем фичу B, мы неявно изменяем и фичу A. В небольшом приложении, возможно, это не так критично. Но чем больше людей работает над проектом и чем объемнее кодовая база, тем сложнее держать в голове все связи между модулями. Данное правило позволяет стандартизировать этот процесс, упрощает рефакторинг и модификацию модулей. Перед тем, как рассмотрим каждый слой отдельно, несколько общих советов по внедрению FSD: Понимание методологии должно быть у всех разработчиков в команде. Новые разработчики должны в обязательном порядке прочитать документацию о FSD. В противном случае пользы от внедрения методологии точно не будет. Глобальные изменения в архитектуре необходимо обсуждать всей командой. Важно периодически проводить анализ архитектуры на наличие кросс-импортов и «болей» в кодовой базе. В целом, совет актуален и для архитектур других видов.  Необязательно использовать FSD на «полную мощь» со всеми уровнями абстракции и видами слоев. Проекты могут существенно отличаться, опыт разработчиков тоже разный, поэтому лучше, чтобы команда сама договорилась о нужном уровне декомпозиции. В процессе разработки этот параметр всегда можно подстроить, чтобы найти свой оптимальный баланс между легкостью внедрения и преимуществами методологии. Рассмотрим каждый слой подробно — от самого нижнего до самого верхнего. 1. Shared — самый абстрактный слой приложения, который содержит переиспользуемые модули, не связанные с бизнес-логикой. Этот слой хорошо подходит для начала применения FSD. В наших проектах эта директория делится на несколько сегментов, некоторых из которых нет в FSD: shared/api — работа с API. shared/config — модуль конфигурации приложения и его окружения.  shared/hooks — кастомные хуки. shared/lib — различные утилитарные функции и вспомогательные библиотеки. shared/themes — список цветов и тем приложения. shared/ui — UI-компоненты: Input, Select, Table и другие.  Самое главное — не путать абстрактные UI-компоненты с компонентами, реализующими конкретные бизнес-сущности или фичи. К примеру, Select — это Shared/UI-компонент, а CitySelect — уже фича. При создании того или иного модуля нужно оценить, будут ли использоваться бизнес-сущности в компоненте. Если нет — модуль необходимо назвать максимально абстрактно и поместить в Shared. В противном случае, желательно указать в названии бизнес-сущность или фичу, которую модуль реализует, и поместить в слой Entities или Features. От грамотного нейминга в этой методологии зависит очень многое.  2. Entities — это компоненты, связанные с представлением бизнес-сущностей, «кирпичики», с помощью которых происходит построение бизнес-логики. Этот слой стоит внедрять желательно вместе со слоем Features, о котором расскажу ниже. 3. Features — части функциональности приложения. Пожалуй, самый сложный для понимания и определения слой в методологии, так как само определение «фичи» зависит от конкретной прикладной области и бизнес-требований. Поэтому при переходе на FSD нужно внедрять «фичи»  только при полной уверенности, что это не внесет дополнительную сложность для разработчиков. Изначально в нашей команде было проблемно определить разницу между Features и Entities. После нескольких обсуждений мы договорились, что фича — это полезная и, желательно, одна функциональность для пользователя, а сущность — то, с помощью чего реализуется эта функциональность. Например, City, Product — сущности, а SearchByCity, BuyProduct — фичи. 4. Widgets — самостоятельные и полноценные блоки страниц с конкретными действиями. Слой также хорошо подходит для начала применения FSD: в разных страницах одного приложения многие части часто повторяются. Чтобы не дублировать их реализацию, части можно выносить в виджеты.  5. Со слоем Pages, я думаю, все просто и понятно — это страницы нашего приложения. Методология советует, чтобы каждая страница имела максимально простую структуру, а бизнес-логику переносить на более низкие слои. Поэтому страница — это композиция из виджетов и/или фич, которая отображает взаимодействие между нижележащими слоями.  6. Следующего слоя в FSD нет, но наша команда решила вынести логику работы с роутами в отдельный слой, чтобы не перегружать слой App или Pages. Если разработчик захочет, например, добавить новый роут или изменить адрес существующего, он точно будет знать, в каком месте вносить правки, а не искать среди большого количества оберток. 7. В папке Processes находится логика, которая затрагивает несколько страниц или все приложение. В нашем проекте мы вынесли в этот слой аутентификацию, так как она влияет на работу всего приложения inDrive. 8. В App находится общая инициализирующая логика приложения — различные обертки, глобальные сторы и стили. В общем, все то, что влияет на работу всего приложения. Основная сложность FSD заключается в более высоком пороге входа по сравнению с другими распространенными подходами. Разработчику приходится учиться понимать потребности пользователя и цели бизнеса.  Если проект начат с нуля по FSD, то первоначально все концепции, описанные выше, кажутся ненужными и переусложненными. Я за то, чтобы внедрять новые слои и уровни декомпозиции только в тот момент, когда команда действительно осознает, что они ей нужны. Иначе большое количество слоев может навредить и запутать разработчиков. Да и сама методология, как я писал выше, не обязывает использовать все подходы.  Эти сложности в полной мере компенсируется преимуществами в виде упрощения онбординга, командного взаимодействия и единой терминологии. Методология подталкивает разработчиков сфокусироваться на задачах бизнеса и отражать их в коде. Тогда (в идеале, конечно) никому не придется объяснять, ради чего создавался тот или иной модуль.Источники: Официальная документация по методологии FSD.  Отличный доклад от одного из соавторов методологии.   Frontend developer