Перейти к основному содержимому

Обзор

Feature-Sliced Design (FSD) — это архитектурная методология для проектирования фронтенд-приложений. Проще говоря, это набор правил и соглашений по организации кода. Главная цель этой методологии — сделать проект понятнее и стабильнее в условиях постоянно меняющихся бизнес-требований.

Помимо набора правил, FSD — это также целый инструментарий. У нас есть линтер для проверки архитектуры вашего проекта, генераторы папок через CLI или IDE, а также богатая библиотека примеров.

Подходит ли FSD мне?

FSD можно внедрять в проектах и командах любого размера. Она подходит для вашего проекта, если:

  • Вы занимаетесь фронтенд-разработкой (интерфейсы для сайтов, мобильных/десктопных приложений, и т. д.)
  • Вы разрабатываете приложение, а не библиотеку

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

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

Базовый пример

Вот простой проект, реализующий FSD:

  • 📁 app
  • 📁 pages
  • 📁 shared

Эти папки верхнего уровня называются слоями. Давайте посмотрим глубже:

  • 📂 app
    • 📁 routes
    • 📁 analytics
  • 📂 pages
    • 📁 home
    • 📂 article-reader
      • 📁 ui
      • 📁 api
    • 📁 settings
  • 📂 shared
    • 📁 ui
    • 📁 api

Папки внутри 📂 pages называются слайсами. Они делят слой по домену (в данном случае, по страницам).

Папки внутри 📂 app, 📂 shared и 📂 pages/article-reader называются сегментами, и они делят слайсы (или слои) по техническому назначению, то есть по тому, для чего предназначен код.

Понятия

Слои, слайсы и сегменты образуют иерархию, как показано на схеме:

Иерархия концепций FSD, описанная ниже

На картинке выше: три столбика, обозначенные слева направо как "Слои", "Слайсы" и "Сегменты" соответственно.

Столбик "Слои" содержит семь делений, расположенных сверху вниз и обозначенных "app", "processes", "pages", "widgets", "features", "entities" и "shared". Деление "processes" зачеркнуто. Деление "entities" соединено со вторым столбиком "Слайсы", показывая, что второй столбик является содержимым "entities".

Столбик "Слайсы" содержит три деления, расположенных сверху вниз и обозначенных "user", "post" и "comment". Деление "post" соединено со столбиком "Сегменты" таким же образом, что и содержимое "post".

Столбик "Сегменты" содержит три деления, расположенных сверху вниз и обозначенных "ui", "model" и "api".

Слои

Слои стандартизированы во всех проектах FSD. Вам не обязательно использовать все слои, но их названия важны. На данный момент их семь (сверху вниз):

  1. App* — всё, благодаря чему приложение запускается — роутинг, точки входа, глобальные стили, провайдеры и т. д.
  2. Processes (процессы, устаревший) — сложные межстраничные сценарии.
  3. Pages (страницы) — полные страницы или большие части страницы при вложенном роутинге.
  4. Widgets (виджеты) — большие самодостаточные куски функциональности или интерфейса, обычно реализующие целый пользовательский сценарий.
  5. Features (фичи) — повторно используемые реализации целых фич продукта, то есть действий, приносящих бизнес-ценность пользователю.
  6. Entities (сущности) — бизнес-сущности, с которыми работает проект, например user или product.
  7. Shared* — переиспользуемый код, особенно когда она отделена от специфики проекта/бизнеса, хотя это не обязательно.

* — эти слои, App и Shared, в отличие от других слоев, не имеют слайсов и состоят из сегментов напрямую.

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

Слайсы

Дальше идут слайсы, они делят слой по предметной области. Вы можете называть ваши слайсы как угодно, и создавать их сколько угодно. Слайсы помогают не теряться в проекте, потому что группируют тесно связанный по смыслу код.

Слайсы не могут использовать другие слайсы на том же слое, и это обеспечивает сильную связанность кода внутри слайса и слабую сцепленность между слайсами.

Сегменты

Слайсы, а также слои App и Shared, состоят из сегментов, а сегменты группируют код по его назначению. Имена сегментов не зафиксированы стандартом, но существует несколько общепринятых имен для наиболее распространенных целей:

  • ui — всё, что связано с отображением: UI-компоненты, форматтеры дат, стили и т.д.
  • api — взаимодействие с бэкендом: функции запросов, типы данных, мапперы.
  • model — модель данных: схемы валидации, интерфейсы, хранилища и бизнес-логика.
  • lib — библиотечный код, который нужен другим модулям этого слайса.
  • config — файлы конфигурации и фиче-флаги.

Обычно этих сегментов достаточно для большинства слоев, поэтому свои собственные сегменты обычно создают только в Shared или App, но это не жёсткое правило.

Преимущества

  • Однородность
    Поскольку структура стандартизирована, проекты становятся более единообразными, что облегчает набор новых участников в команду.

  • Устойчивость к изменениям и рефакторингу
    Модуль на одном слое не может использовать другие модули на том же слое или слоях выше.
    Это позволяет вам вносить изолированные правки без непредвиденных последствий для остальной части приложения.

  • Контролируемое переиспользование логики
    В зависимости от уровня вы можете сделать код либо очень переиспользуемым, либо очень локальным.
    Это сохраняет баланс между соблюдением принципа DRY и практичностью.

  • Ориентация на потребности бизнеса и пользователей
    Приложение разделено на бизнес-домены, и при именовании поощряется использование терминологии бизнеса, чтобы вы могли делать полезную работу в продукте, не вникая полностью во все другие несвязанные части проекта.

Постепенное внедрение

Если у вас есть существующая кодовая база, которую вы хотите перенести на FSD, мы предлагаем следующую стратегию. На нашем собственном опыте миграции она хорошо себя зарекомендовала.

  1. Начните постепенно формировать слои App и Shared, чтобы создать фундамент.

  2. Раскидайте весь существующий интерфейсный код по виджетам и страницам, даже если у них пока что есть зависимости, нарушающие правила FSD.

  3. Постепенно исправляйте нарушения правил на импорты, а по ходу извлекайте сущности и, возможно, фичи.

Рекомендуется воздержаться от добавления новых крупных сущностей во время рефакторинга, а также рефакторинга по частям.

Следующие шаги

  • Хотите разобраться в том, как мыслить по-FSD-шному? Прочтите Туториал.
  • Предпочитаете учиться на примерах? У нас их много в разделе Примеры.
  • Есть вопросы? Загляните в наш чат Telegram и спросите у сообщества.