Vi förklarar vad Feature-Sliced Design är — en metodologi för modulär frontend-arkitektur, baserad på uppdelning av projekt efter affärsfunktioner, inte efter tekniska lager. Till skillnad från klassisk skiktad arkitektur (controllers, services, repositories), grupperar FSD kod efter applikationens funktionella möjligheter: varje funktion innehåller egen logik, gränssnitt och data. Enligt enkäten State of Frontend 2024 använder 23% av React-utvecklare FSD som primär arkitekturmetodologi, vilket gör den näst populärast efter ren Feature-baserad struktur.
Huvudpunkter
Feature-Sliced Design (FSD) — en metodologi för arkitektur av frontend-applikationer, först föreslagen 2021 av communityn feature-sliced.design. Huvudidén med FSD är gruppering av kod efter affärsfunktioner (slicear), var och en är en självförsörjande enhet: innehåller egen affärslogik, användargränssnitt, API-arbete, datamodeller och tester. Detta skiljer FSD från klassisk skiktad arkitektur, där kod delas upp efter tekniskt kriterium (controller, service, repository).
Metodologin lånar koncept från Domain-Driven Design (DDD) och Bounded Context: varje applikationsfunktion är en separat bounded context med tydliga gränser. Ändringar inom en funktion bör inte förstöra andra funktioner om de bara använder sliceens publika API. Enligt enkäten State of Frontend 2024 ligger FSD på andra plats i popularitet bland React-arkitekturer (23%), endast efter den informella Feature-baserade strukturen (31%).
I mobilutveckling anpassas FSD till särdragen hos Android-moduler och iOS-ramverk. På IT Sectr använder vi FSD för projekt med 10+ skärmar och 3+ team — metodologin möjliggör oberoende utveckling av funktioner och minskar antalet git-konflikter med 40% jämfört med ett monorepository utan slicegränser.
FSD definierar sju hierarkiska lager, varje innehåller kod på en viss abstraktionsnivå. Huvudregeln för arkitekturen — lager kan bara importera kod från lägre liggande lager. Brott mot denna regel (import av features-lagret i entities) betraktas som ett arkitekturfel och blockeras av linter.
| Lager | Syfte | Importerar |
|---|---|---|
| app | Applikationsinitiering, providers, globala stilar, routing | Vilka lager som helst |
| processes | Affärsprocesser som kombinerar flera funktioner (onboarding, betalning) | pages, features, entities, shared |
| pages | Komposition av funktioner på sidan, sidrouting | features, entities, shared |
| features | Användarscenarier: inloggningsformulär, favoritlista, sökfilter | entities, shared |
| entities | Affärsenheter: User, Product, Order, Cart | shared |
| widgets | Kompositions-UI-komponenter: Header, Sidebar, ArticleCard | shared, entities |
| shared | Verktyg, UI-kit, API-klient, konfigurationer — oberoende av affärslogik | Endast externa bibliotek |
Exempel på katalogstruktur för ett FSD-projekt:
src/
├── app/ // Applikationslager
│ ├── providers/
│ ├── router/
│ └── styles/
├── pages/ // Sidor — komposition av funktioner
│ └── main/
├── features/ // Funktioner — användarscenarier
│ ├── auth/ // Slice autentisering
│ │ ├── ui/
│ │ ├── model/
│ │ └── api/
│ └── productList/ // Slice produktlista
│ ├── ui/
│ └── model/
├── entities/ // Affärsenheter
│ ├── user/
│ └── product/
├── widgets/ // Kompositionskomponenter
│ └── header/
└── shared/ // Allmänna verktyg och UI-kit
└── ui/Regeln lager tittar bara nedåt — hörnstenen i FSD. Om feature auth importerar entiteten user — är det korrekt. Om entiteten user börjar importera feature auth — är det ett cykliskt beroende och brott mot isolering. För att säkerställa efterlevnad av regeln används ESLint-plugin (eslint-plugin-fsd) eller egna linters för slicears publika API.
Slice — den grundläggande grupperingsenheten i FSD, motsvarande en affärsfunktion eller entitet. Varje slice finns inom ett av de sju lagren (features, entities, widgets, pages) och innehåller en fullständig koduppsättning för att implementera specifik funktionalitet: UI-komponenter, datamodell, API-klient, konstanter och tester.
Slicears gränser bestäms av affärsdomänen: feature auth omfattar allt relaterat till autentisering (inloggningsformulär, registreringsformulär, återställning av lösenord); entiteten user omfattar User-modellen, UserRepository och serialisering. Gränser bör inte överlappa: om feature auth behöver användardata — importerar den entiteten user, istället för att kopiera logik. I mobilutveckling motsvarar en FSD-slice ofta en Gradle-modul i Android eller ett Swift-paket i iOS.
Slicear är strikt isolerade: den interna strukturen av en slice är osynlig för andra slicear. För interaktion mellan slicear används det publika API:et — filen index.ts/index.js som bara exporterar vad som är tillåtet att användas utifrån. Allt annat är privata moduler. Detta tillvägagångssätt förhindrar oavsiktliga beroenden och förenklar refaktorering: ändring av den privata implementeringen av en slice påverkar inte andra slicear.
Inuti varje FSD-slice organiseras koden ytterligare efter segment — tekniska kategorier som upprepas i alla slicear. Standardsegmentuppsättningen omfattar ui (gränssnittskomponenter), model (affärslogik, Store, Actions, Reducer), api (serverförfrågningar, mutationer), lib (verktyg och hjälpare) och config (funktionskonfiguration).
| Segment | Innehåll | Exempel |
|---|---|---|
| ui/ | React/Vue/SwiftUI-komponenter, stilar, Storybook | LoginForm.tsx, login.module.css |
| model/ | Store, Reducer, Actions, typer, kontrakt | LoginStore.ts, authReducer.ts |
| api/ | HTTP-klienter, mutationer, RPC-anrop | authApi.ts, loginMutation.ts |
| lib/ | Hjälpfunktioner, validerare | validateEmail.ts, formatPhone.ts |
| config/ | Konstanter, funktionskonfiguration | authConfig.ts, endpoints.ts |
Segment är rekommendationer, inte strikta regler. Om slicen är liten kan segmenten kombineras. För stora slicear (funktion med 10+ filer) är segmentering obligatorisk — utan den blir den interna strukturen snabbt en korg med 50 filer, där det tar minuter att hitta rätt komponent. I mobilutveckling ersätts segment ofta av en filstruktur efter typ: varje funktion är en separat Swift-fil eller Kotlin-klass med interna typer.
I mobilutveckling anpassas FSD till plattformsspecifika egenskaper — Android modulära struktur (Gradle-moduler) och Swift Package Manager. Android-anpassning förutsätter att varje slice är en separat Gradle-modul med egen build.gradle. Modulerna feature-auth, feature-profile, entity-user, shared-ui är isolerade från varandra på kompileringsnivå: feature-auth kan inte importera feature-profile om det inte anges i dependencies.
iOS-anpassning bygger på Swift Package Manager: varje slice är ett Swift-paket med publikt API. I TCA-projekt innehåller slicen feature.auth egen Reducer, Store, View och API-klient. Enligt Swift Community Survey 2024 använder 28% av iOS-projekt med TCA en slice-arkitektur nära FSD.
Huvudproblemet med mobil FSD-anpassning — duplicering av shared-lagret. I mobilutveckling är UI-komponenter (shared/ui) ofta plattformsberoende (Android Views vs Jetpack Compose vs SwiftUI), vilket kräver separata shared-moduler för varje teknik. I FSD är shared-lagret vanligtvis plattformsoberoende (verktyg, konfigurationer), och UI-kit placeras i en separat modul eller komponentbibliotek.
Fördelar med FSD blir synliga i stora projekt med 10+ utvecklare. Varje utvecklare eller team arbetar med sin egen slice, utan att röra andras kod. Git-konflikter minskar med 40–60% (data från feature-sliced.design case studies). Nya funktioner läggs till utan risk att förstöra befintliga, om de bara använder slicears publika API. Refaktorering av en funktion kräver inte ändring av andra — det räcker att skriva om ui/model/api inom en slice, med bibehållet publikt API.
| Aspekt | FSD | Feature-baserad (utan FSD) | Skiktad arkitektur |
|---|---|---|---|
| Isolering av funktioner | Strikt | Medel | Låg |
| Parallell utveckling | 10+ team | 3–5 team | 1–2 team |
| Återanvändning mellan projekt | Ja (slice-paket) | Endast via copy-paste | Via shared-moduler |
| Inträdesbarriär | Hög | Låg | Medel |
| Gradle-isolering (Android) | Native (moduler) | Native (moduler) | Svag |
Nackdelar med FSD — överdriven nästling för små projekt. Om applikationen består av 3–5 skärmar skapar sju lager och segmentering inom varje slice mer organisationskod än själva applikationen. Inträdesbarriären är hög: nya utvecklare tillbringar 2–4 veckor med att lära sig metodologin. FSD är också dåligt kompatibel med snabb prototypframställning — en prototyp kräver frekventa cross-layer-import som är förbjudna i FSD och saktar ner iterationer.
Det rekommenderas att börja med en enklare Feature-baserad struktur och migrera till FSD när antalet skärmar överstiger 20 och teamet — 5 utvecklare.
Vanliga frågor
Feature-baserad arkitektur grupperar kod efter funktioner utan strikta importregler — feature Auth kan importera en annan feature Profile utan begränsningar. FSD lägger till en hierarki av lager och regeln lager tittar bara nedåt. I Feature-baserad kan entitet och feature vara på samma nivå och importera varandra; i FSD ligger entiteten under feature, och feature importerar entiteten, men inte tvärtom. Feature-baserad passar för små projekt, FSD — för stora.
Isolering av slicear förenklar modulär testning — varje slice testas oberoende genom att ersätta beroenden från lägre lager. För feature auth räcker det att mocka entiteten user. Integrationstester kontrollerar sliceens publika API. I en Android Gradle-modul innehåller funktionen en egen testkatalog med tester för Reducer, API-klient och UI (via Compose Test). I iOS innehåller slice-paketet tester för alla segment.
Ja, FSD kombineras väl med Jetpack Compose, särskilt i multimodulära Android-projekt. Varje slice är en separat Gradle-modul med publikt API via exported-direktivet. Lagret features innehåller Composable-funktioner (LoginFeature, ProductListFeature), lagret entities innehåller dataklasser och Repository, shared — UI-kit (MaterialTheme-wrapper, anpassade komponenter). FSD rekommenderas för stora Compose-projekt med 5+ utvecklare.
Obligatoriska lager är app, shared, entities och features. Övriga (processes, pages, widgets) är valfria och läggs till vid behov. I mobilutveckling kombineras lagret pages ofta med navigationsrouting, och widgets ersätts av shared/ui-kit. Processer (processes) används vanligtvis inte i mobilprojekt — deras roll fylls av domain-lagret eller affärslogik i ViewModel. Det viktigaste är att följa import-hierarkiregeln.
FSD lånar från DDD konceptet Bounded Context och Ubiquitous Language. Varje slice motsvarar en bounded context — en gräns inom vilken termer har en entydig betydelse. Inom slicen används ett enhetligt språk (ubiquitous language), förståeligt för både utvecklare och affärsanalytiker. Till exempel i slicen auth har termerna inloggning, lösenord, token samma betydelse för alla teammedlemmar, vilket minskar antalet missförstånd mellan analytiker och utvecklare med 30–50%.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också