Обясняваме какво е Feature-Sliced Design — методология за модулна фронтенд архитектура, основана на разделяне на проекта по бизнес функции, а не по технически слоеве. За разлика от класическата слоеста архитектура (контролери, услуги, хранилища), FSD групира кода по функционални възможности на приложението: всяка функция съдържа собствена логика, интерфейс и данни. Според данните от проучването 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 с ясни граници. Промените в една функция не трябва да развалят други функции, ако те използват само публичния 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. Ако функцията auth импортира единицата user — това е коректно. Ако единицата user започне да импортира функцията auth — това е циклична зависимост и нарушение на изолацията. За осигуряване на спазването на правилото се използват ESLint приставки (eslint-plugin-fsd) или собствени линтери на публичния API на слайсовете.
Слайс (slice) — основната единица за групиране в FSD, съответстваща на една бизнес функция или единица. Всеки слайс се намира в един от седемте слоя (features, entities, widgets, pages) и съдържа пълен набор от код за реализиране на конкретна функционалност: UI компоненти, модел на данни, API клиент, константи и тестове.
Границите на слайсовете се определят от бизнес домейна: функцията auth включва всичко, свързано с удостоверяване (форма за вход, форма за регистрация, нулиране на парола); единицата user включва User модел, UserRepository и сериализация. Границите не трябва да се припокриват: ако функцията auth се нуждае от данни за потребителя — тя импортира единицата 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 |
Сегментите са препоръка, а не строго правило. Ако слайсът е малък, сегментите могат да се комбинират. За големи слайсове (функция с 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% (данни от case studies на feature-sliced.design). Нови функции се добавят без риск да развалят съществуващите, ако използват само публичния 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 архитектурата групира кода по функции без строги правила за импорт — функцията Auth може да импортира друга функция Profile без ограничения. FSD добавя йерархия от слоеве и правилото „слоевете гледат само надолу". В Feature-based единицата и функцията могат да бъдат на едно ниво и да се импортират взаимно; в FSD единицата е под функцията и функцията импортира единицата, но не и обратно. Feature-based подхожда за малки проекти, FSD — за големи.
Изолацията на слайсовете опростява модулното тестване — всеки слайс се тества независимо чрез заместване на зависимостите на по-ниските слоеве. За функцията auth е достатъчно да мокнете единицата 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 често се обединява с навигационно маршрутизиране, а 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 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също