Feature-Sliced Design
Слои, слайсы, сегменты, правило импортов и FSD с Next.
Обновлено
Что такое Feature-Sliced Design
Feature-Sliced Design (FSD) — методология архитектуры фронтенда со строгими правилами о том, куда класть код и кто что может импортировать. Код делится по тому, насколько он специфичен для бизнеса — от страниц (очень специфичных) до утилит (общих).
Feature-Sliced Design за 1 минуту
FSD организует код на 3 уровнях: слои (layers) → слайсы (slices) → сегменты (segments).
src/app/глобальная настройка: провайдеры, стили, инициализацияviews/страницы (в FSD «pages»; переименовано, чтобы не путать с Next)widgets/крупные составные блоки UI: шапка, сайдбар, playgroundfeatures/действия пользователя с бизнес-ценностью: run-exercise, add-to-cartentities/бизнес-сущности: user, lesson, product, progressshared/общий код без бизнеса: ui kit, lib, api client, config
Золотое правило
Слой может импортировать только из слоёв ниже себя.
views→widgets→features→entities→sharedfeatures/run-exerciseможет использоватьentities/exercise✓entities/exerciseНЕ может использоватьfeatures/...✗- Два слайса одного слоя не импортируют друг друга (
features/a✗→features/b). Их объединяют уровнем выше (widget/view).
Слайсы и сегменты
Слайс = одно понятие (entities/lesson). Внутри — сегменты по технической роли:
| Сегмент | Содержит |
|---|---|
ui/ |
компоненты |
model/ |
типы, состояние, стор, хуки с логикой |
api/ |
запросы, query, server actions |
lib/ |
хелперы этого слайса |
config/ |
константы |
Как мы используем его в этом проекте
app/[locale]/[topic]/[lesson]/page.tsxтолько собирает viewsrc/views/lesson/ui/lesson-view.tsxwidgets/playground/ui/playground.tsxfeatures/run-exercise/lib/run-js.tsentities/lesson/api/lesson-api.tsui/lesson-content.tsx
Наше соглашение: без index.ts, который реэкспортирует, — импортируем прямо из файла, с описательными именами в kebab-case. Официальный FSD рекомендует index.ts как публичный API каждого слайса; мы от него отказываемся ради более лёгкого поиска, быстрого dev-сервера и нуля случайных циклических зависимостей. Цена: дисциплина «не импортируй внутренние детали» лежит на вас, а не на структуре.
FSD + Next App Router
- Корневая папка
app/— это роутинг Next: тонкие файлы, которые импортируют изviews. - Слой FSD
pages→ мы называем егоviews(чтобы не путать с Pages Router). - Слой FSD
app(провайдеры, глобальный CSS) может жить вapp/layout.tsxили вsrc/app.
Плюсы / минусы
| Плюсы | Минусы |
|---|---|
| понятные правила: знаете, куда положить что угодно | кривая обучения, «это entity или feature?» |
| нет циклических импортов | слишком много для маленьких проектов |
| масштабируется на большие команды | много переходов между папками |
| удалить фичу = удалить папку | нужен линтер (Steiger), чтобы оставалось чисто |
Коротко
- 6 слоёв от специфичного к общему: app → views → widgets → features → entities → shared.
- Импорты только вниз; слайсы одного слоя не импортируют друг друга.
- У нас: без barrel-файлов, описательные файлы в kebab-case, корневой
app/— только для роутинга.