Feature-Sliced Design
Straturi, slice-uri, segmente, regula importurilor și FSD cu Next.
Actualizat
Ce este Feature-Sliced Design
Feature-Sliced Design (FSD) e o metodologie de arhitectură pentru frontend, cu reguli stricte despre unde pui codul și cine ce poate importa. Codul e împărțit după cât de specific e pentru business — de la pagini (foarte specifice) până la utilitare (generice).
Feature-Sliced Design în 1 minut
FSD organizează codul pe 3 niveluri: straturi (layers) → felii (slices) → segmente (segments).
src/app/configurare globală: providers, stiluri, initviews/pagini (în FSD „pages”; redenumit ca să nu se bată cu Next)widgets/blocuri mari de UI compuse: header, sidebar, playgroundfeatures/acțiuni ale userului cu valoare de business: run-exercise, add-to-cartentities/concepte de business: user, lesson, product, progressshared/cod generic, fără business: ui kit, lib, api client, config
Regula de aur
Un strat poate importa doar din straturile de sub el.
views→widgets→features→entities→sharedfeatures/run-exercisepoate folosientities/exercise✓entities/exerciseNU poate folosifeatures/...✗- Două slice-uri din același strat nu se importă între ele (
features/a✗→features/b). Le combini un nivel mai sus (widget/view).
Slice-uri și segmente
Slice = un concept (entities/lesson). În el, segmente după rol tehnic:
| Segment | Conține |
|---|---|
ui/ |
componente |
model/ |
tipuri, state, store, hook-uri de logică |
api/ |
request-uri, query-uri, server actions |
lib/ |
helpers specifici slice-ului |
config/ |
constante |
Cum îl folosim în proiectul ăsta
app/[locale]/[topic]/[lesson]/page.tsxdoar compune view-ulsrc/views/lesson/ui/lesson-view.tsxwidgets/playground/ui/playground.tsxfeatures/run-exercise/lib/run-js.tsentities/lesson/api/lesson-api.tsui/lesson-content.tsx
Convenția noastră: fără index.ts care re-exportă — importăm direct din fișier, cu nume descriptive kebab-case. FSD oficial recomandă un index.ts ca public API al fiecărui slice; noi renunțăm la el pentru căutare mai ușoară, dev server mai rapid și zero dependențe circulare accidentale. Costul: disciplina „nu importa detalii interne” e pe tine, nu pe structură.
FSD + Next App Router
- Folderul
app/de la rădăcină e routing-ul Next — fișiere subțiri care importă dinviews. - Stratul
pagesdin FSD → îl numimviews(evităm confuzia cu Pages Router). - Stratul FSD
app(providers, global CSS) poate trăi înapp/layout.tsxsau însrc/app.
Plusuri / minusuri
| Plusuri | Minusuri |
|---|---|
| reguli clare: știi unde pui orice | curbă de învățare, „e entity sau feature?” |
| fără importuri circulare | prea mult pentru proiecte mici |
| scalează la echipe mari | mulți pași de navigare între foldere |
| ștergi un feature = ștergi un folder | necesită lint (Steiger) ca să rămână curat |
Pe scurt
- 6 straturi, de la specific la generic: app → views → widgets → features → entities → shared.
- Importuri doar în jos; slice-urile din același strat nu se importă între ele.
- La noi: fără barrel-uri, fișiere kebab-case descriptive,
app/de la rădăcină doar pentru routing.