Рассказываем, что такое Feature-Sliced Design — методология модульной архитектуры фронтенда, основанная на разделении проекта по бизнес-фичам, а не по техническим слоям. В отличие от классической слоистой архитектуры (контроллеры, сервисы, репозитории), FSD группирует код по функциональным возможностям приложения: каждая фича содержит собственную логику, UI и данные. По данным опроса State of Frontend 2024, FSD используют 23% React-разработчиков как основную архитектурную методологию, что делает её второй по популярности после чистой Feature-based структуры.
Главное
Feature-Sliced Design (FSD) — методология архитектуры фронтенд-приложений, впервые предложенная в 2021 году сообществом feature-sliced.design. Основная идея FSD — группировка кода по бизнес-фичам (слайсам), каждая из которых является самодостаточной единицей: содержит собственную бизнес-логику, пользовательский интерфейс, работу с API, модели данных и тесты. Это отличает FSD от классической слоистой архитектуры, где код разделён по техническому признаку (controller, service, repository).
Методология заимствует концепции Domain-Driven Design (DDD) и Bounded Context: каждая фича приложения — это отдельный bounded context c чёткими границами. Изменения внутри одной фичи не должны ломать другие фичи, если они используют только публичное API слайса. По данным опроса State of Frontend 2024, FSD занимает второе место по популярности среди React-архитектур (23%), уступая только неформальной Feature-based структуре (31%).
В мобильной разработке FSD адаптируется под особенности Android-модулей и iOS-фреймворков. В IT Sectr мы используем FSD для проектов с 10+ экранами и 3+ командами — методология позволяет независимо разрабатывать фичи и снижает число конфликтов в git на 40% по сравнению с монорепозиторием без слайс-границ.
FSD определяет семь иерархических слоёв, каждый из которых содержит код определённого уровня абстракции. Главное архитектурное правило — слои могут импортировать только код из нижележащих слоёв. Нарушение этого правила (импорт слоя features в entities) считается архитектурной ошибкой и блокируется линтером.
| Слой | Назначение | Импортирует |
|---|---|---|
| app | Инициализация приложения, провайдеры, глобальные стили, роутинг | Любые слои |
| processes | Бизнес-процессы, объединяющие несколько фич (онбординг, оплата) | pages, features, entities, shared |
| pages | Композиция фич на странице, роутинг страниц | features, entities, shared |
| features | Пользовательские сценарии: форма входа, список избранного, фильтр поиска | entities, shared |
| entities | Бизнес-сущности: User, Product, Order, Cart | shared |
| widgets | Композиционные компоненты UI: Header, Sidebar, ArticleCard | shared, entities |
| shared | Утилиты, UI-kit, API-клиент, конфиги — независимый от бизнес-логики | Только внешние библиотеки |
Пример структуры директорий FSD-проекта:
src/
├── app/ // Слой приложения
│ ├── providers/
│ ├── router/
│ └── styles/
├── pages/ // Страницы — композиция фич
│ └── main/
├── features/ // Фичи — пользовательские сценарии
│ ├── auth/ // Слайс «Авторизация»
│ │ ├── ui/
│ │ ├── model/
│ │ └── api/
│ └── productList/ // Слайс «Список товаров»
│ ├── ui/
│ └── model/
├── entities/ // Бизнес-сущности
│ ├── user/
│ └── product/
├── widgets/ // Композиционные компоненты
│ └── header/
└── shared/ // Общие утилиты и UI-kit
└── ui/Правило «слои смотрят только вниз» — краеугольный камень FSD. Если feature auth импортирует entity user — это корректно. Если entity user начинает импортировать feature auth — это циклическая зависимость и нарушение изоляции. Для обеспечения правила используются ESLint-плагины (eslint-plugin-fsd) или собственные линтеры публичного API слайсов.
Слайс (slice) — основная единица группировки в FSD, соответствующая одной бизнес-фиче или сущности. Каждый слайс находится внутри одного из семи слоёв (features, entities, widgets, pages) и содержит полный набор кода для реализации конкретной функциональности: UI-компоненты, модель данных, API-клиент, константы и тесты.
Границы слайсов определяются бизнес-доменом: feature auth включает всё, что связано с авторизацией (форма входа, форма регистрации, сброс пароля); entity user включает User-модель, UserRepository и сериализацию. Границы не должны пересекаться: если в feature auth нужны данные о пользователе — она импортирует entity user, а не копирует логику. В мобильной разработке слайс FSD часто соответствует Gradle-модулю в Android или Swift-пакету в iOS.
Слайсы строго изолированы: внутренняя структура одного слайса невидима для других слайсов. Для взаимодействия между слайсами используется публичное API — файл index.ts/index.js, который экспортирует только то, что разрешено к использованию снаружи. Всё остальное — приватные модули. Такой подход предотвращает случайные зависимости и упрощает рефакторинг: изменение приватной реализации одного слайса не затрагивает другие слайсы.
Внутри каждого слайса FSD код дополнительно организуется по сегментам — техническим категориям, которые повторяются во всех слайсах. Стандартный набор сегментов включает ui (компоненты интерфейса), model (бизнес-логика, Store, Actions, Reducer), api (запросы к серверу, мутации), lib (утилиты и хелперы) и config (конфигурация фичи).
| Сегмент | Содержимое | Пример |
|---|---|---|
| ui/ | React/Vue/SwiftUI компоненты, стили, Storybook | LoginForm.tsx, login.module.css |
| model/ | Store, Reducer, Actions, типы, контракты | LoginStore.ts, authReducer.ts |
| api/ | HTTP-клиенты, мутации, RPC-вызовы | authApi.ts, loginMutation.ts |
| lib/ | Вспомогательные функции, валидаторы | validateEmail.ts, formatPhone.ts |
| config/ | Константы, конфигурация фичи | authConfig.ts, endpoints.ts |
Сегменты — рекомендация, а не строгое правило. Если слайс маленький, сегменты можно объединять. Для крупных слайсов (feature с 10+ файлами) сегментация обязательна — без неё внутренняя структура быстро превращается в «корзину» из 50 файлов, где поиск нужного компонента занимает минуты. В мобильной разработке сегменты часто заменяются на файловую структуру по типу: каждая фича — отдельный Swift файл или Kotlin-класс с внутренними типами.
В мобильной разработке FSD адаптируется под платформенные особенности — модульную структуру Android (Gradle-модули) и Swift Package Manager. Android-адаптация предполагает, что каждый слайс — отдельный Gradle-модуль со своим build.gradle. Модули feature-auth, feature-profile, entity-user, shared-ui изолированы друг от друга на уровне сборки: feature-auth не может импортировать feature-profile, если это не указано в dependencies.
iOS-адаптация строится на Swift Package Manager: каждый слайс — Swift-пакет с публичным API. В TCA-проектах слайс feature.auth содержит собственный Reducer, Store, View и API-клиент. По данным Swift Community Survey 2024, 28% iOS-проектов с TCA используют слайсовую архитектуру, близкую к FSD.
Основная проблема мобильной адаптации FSD — дублирование слоя shared. В мобильной разработке UI-компоненты (shared/ui) часто зависят от платформы (Android Views vs Jetpack Compose vs SwiftUI), что требует отдельных shared-модулей для каждой технологии. В FSD shared-слой обычно платформенно-независим (утилиты, конфиги), а UI-kit выносится в отдельный модуль или библиотеку компонентов.
Преимущества FSD становятся заметны в больших проектах с 10+ разработчиками. Каждый разработчик или команда занимается своим слайсом, не задевая чужой код. Конфликты в git сокращаются на 40–60% (данные feature-sliced.design case studies). Новые фичи добавляются без риска сломать существующие, если они используют только публичное API слайсов. Рефакторинг одной фичи не требует изменения других — достаточно переписать ui/model/api внутри одного слайса, сохранив публичное API.
| Аспект | FSD | Feature-based (без FSD) | Слоистая архитектура |
|---|---|---|---|
| Изоляция фич | Строгая | Средняя | Низкая |
| Параллельная разработка | 10+ команд | 3–5 команд | 1–2 команды |
| Переиспользование между проектами | Да (слайсы-пакеты) | Только через copy-paste | Через shared-модули |
| Порог входа | Высокий | Низкий | Средний |
| Gradle-изоляция (Android) | Нативная (модули) | Нативная (модули) | Слабая |
Недостатки FSD — избыточная вложенность для маленьких проектов. Если приложение состоит из 3–5 экранов, семь слоёв и сегментация внутри каждого слайса создают больше кода организации, чем самого приложения. Порог входа высок: новые разработчики тратят 2–4 недели на освоение методологии. Также FSD плохо совместим с быстрым прототипированием — прототип требует частых cross-layer импортов, которые в FSD запрещены и замедляют итерации.
Рекомендуется начинать с более простой Feature-based структуры и мигрировать на FSD, когда количество экранов превысит 20, а команда — 5 разработчиков.
Часто задаваемые вопросы
Feature-based архитектура группирует код по фичам без строгих правил импортов — feature Auth может импортировать другой feature Profile без ограничений. FSD добавляет иерархию слоёв и правило «слои смотрят только вниз». В Feature-based entity и feature могут быть на одном уровне и импортировать друг друга; в FSD entity лежит ниже feature, и feature импортирует entity, но не наоборот. Feature-based подходит для небольших проектов, FSD — для крупных.
Изоляция слайсов упрощает модульное тестирование — каждый слайс тестируется независимо подменой зависимостей нижележащих слоёв. Для feature auth достаточно замокать entity user. Интеграционные тесты проверяют публичное API слайса. В Android Gradle-модуль фичи содержит собственный test-каталог с тестами Reducer, API-клиента и UI (через Compose Test). В iOS слайс-пакет включает тесты всех сегментов.
Да, FSD хорошо сочетается с Jetpack Compose, особенно в многомодульных Android-проектах. Каждый слайс — отдельный Gradle-модуль с публичным API через exported-директиву. Слой features содержит Composable-фичи (LoginFeature, ProductListFeature), слой entities — data-классы и Repository, shared — UI-kit (MaterialTheme-wrapper, кастомные компоненты). FSD рекомендован для крупных Compose-проектов с 5+ разработчиками.
Обязательные слои — app, shared, entities и features. Остальные (processes, pages, widgets) опциональны и добавляются по необходимости. В мобильной разработке слой pages часто объединяют с navigation-роутингом, а widgets заменяют на shared/ui-kit. Процессы (processes) обычно не используются в мобильных проектах — их роль выполняет слой domain или бизнес-логика в ViewModel. Главное — соблюдать правило иерархии импортов.
FSD заимствует из DDD концепцию Bounded Context и Ubiquitous Language. Каждый слайс соответствует bounded context — границе, внутри которой термины имеют однозначный смысл. Внутри слайса используется единый язык (ubiquitous language), понятный и разработчикам, и бизнес-аналитикам. Например, в слайсе auth термины «логин», «пароль», «токен» имеют один смысл для всех участников команды, что снижает число недопониманий между аналитиками и разработчиками на 30–50%.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также