Feature-Sliced Design: Как FSD спасает от хаоса в растущих проектах

Константин Потапов
8 мин

Мой главный фаворит в архитектуре фронтенда. Рассказываю, как слои FSD — от shared до pages — превращают бардак в стройную систему, которая масштабируется без боли. Говорю как есть, после внедрения в десятке проектов.

Сначала — боль

Помните, как начинается любой проект? Чистота, порядок, папка components и уверенность, что «в этот раз всё будет иначе».

А через полгода:

  • UserCard неожиданно знает про ProductList
  • ProductList тянет за собой Cart
  • Cart по старой памяти лезет в UserCard
  • Сборка падает с малопонятными циклическими зависимостями
  • А новый SuperButton ты вообще не знаешь, куда приткнуть

Узнали? Это классический спуск в ад под названием «рост проекта без архитектуры».

Что такое FSD и почему я на нём «подсел»

Feature-Sliced Design (FSD) — это не очередная теория из учебника. Это практичная методология, которая раскладывает ваш фронтенд по слоям и слайсам. Она создаёт жёсткие рамки, в которых код остаётся читаемым и поддерживаемым, даже когда команда и функциональность растут как на дрожжах.

После года использования и десятка внедрённых проектов я с уверенностью заявляю: я теперь использую FSD в абсолютно всех своих проектах и невероятно доволен результатом. Это тот самый каркас, которого всем не хватает.

Слои FSD (как этажи в здании)

  1. shared — фундамент: переиспользуемый код без бизнес-логики (UI-кит, утилиты, API-инстансы)
  2. entities — бизнес-сущности (User, Product, Order)
  3. features — пользовательские сценарии, то, ради чего всё затевалось (LoginForm, AddToCart)
  4. widgets — композиции фич и сущностей для страниц (Header, ProductGrid)
  5. pages — готовые страницы приложения
  6. app — инфраструктура (роутинг, провайдеры, глобальные стили)

Золотое правило: импортируем только сверху вниз. Обратные импорты — строгое табу.

// ✅ Всё чисто, живём по правилам
import { Button } from '@/shared/ui'
import { User } from '@/entities/user'
 
// ❌ Такой код должен вызывать чувство стыда и ошибку линтера
// shared → entities
// features → widgets

Почему FSD — это прорыв

1. Наконец-то появилась предсказуемость

Любая новая задача теперь не начинается с вопроса «Куда это положить?». Есть чёткий алгоритм:

  • UI-примитив → shared/ui
  • Бизнес-модель → entities/
  • Пользовательское действие → features/
  • Крупный блок из кусочков → widgets/

2. Переиспользование становится естественным

Нижние слои не зависят от верхних. Это значит, что Button из shared можно тасовать где угодно, не боясь притащить в бандл пол-приложения.

3. Масштабирование перестало быть болью

Новая фича? Просто создаём папку в features/. Она изолирована и не поломает соседей. Команда может работать параллельно, не мешая друг другу.

4. Онбординг новичков ускорился в разы

Новый разработник буквально за 30 минут понимает, где что лежит. Открыл features/ — и вот они, все пользовательские сценарии, как на ладони.

Как это выглядит в реальном проекте (на примере магазина)

src/
├── shared/         # Базовые кирпичики: UI, utils, api
├── entities/       # Бизнес-сущности: user, product, order
├── features/       # Что пользователь делает: auth, add-to-cart, filters
├── widgets/        # Крупные блоки: header, cart-sidebar, product-grid
└── pages/          # Страницы: home, product, cart
// pages/product/ui/ProductPage.tsx
import { Header } from '@/widgets/header'
import { ProductCard } from '@/entities/product'
import { AddToCartButton } from '@/features/add-to-cart'
 
export const ProductPage = ({ product }) => (
  <>
    <Header />
    <ProductCard product={product}>
      <AddToCartButton productId={product.id} />
    </ProductCard>
  </>
)

Сразу видно: страница собирается из виджетов, те — из фич и сущностей. Всё логично и прозрачно.

Грабли, на которые не надо наступать

Смешивание слоёв — корень всех зол

// ❌ Плохо, пахнет спагетти-кодом
import { User } from '@/entities/user' // из shared
 
// ✅ Отлично! shared независим и переиспользуем
type AvatarProps = { src: string; alt: string }
export const Avatar = ({ src, alt }: AvatarProps) => <img src={src} alt={alt} />

Фича-монстр

Фича должна делать одно действие. Если ваш auth превратился в монстра, пора его резать:

features/
├── login/
├── register/
├── password-reset/
└── oauth/

Бизнес-логика в shared

shared — нейтральная территория. Функции вроде formatUserName по праву принадлежат entities/user/lib.

Мой инструментарий для FSD

Контроль на границах — наш всё

Без линтера правила будут постоянно нарушаться. Вот основа:

// .eslintrc.js
{
  "plugins": ["import"],
  "rules": {
    "import/no-restricted-paths": [
      "error",
      {
        "zones": [
          { "target": "./src/shared", "from": "./src/entities" },
          { "target": "./src/entities", "from": "./src/features" }
        ]
      }
    ]
  }
}

CLI-генераторы

Я лично ими не пользуюсь — люблю создавать структуру руками, но для больших команд они могут быть спасением.

npm run fsd create feature add-to-favorites

Что FSD дал лично мне и моим проектам

После перехода на FSD в нескольких крупных проектах (от 5 до 15 разработчиков) результаты говорят сами за себя:

В 2 раза
быстрее онбординг новичков
0
циклических зависимостей в продакшене
На 60%
быстрее код-ревью

Но главное даже не цифры. Это спокойствие. Спокойствие, когда ты заходишь в старый проект и через 5 минут понимаешь, где что искать. Спокойствие, когда добавляешь новую сложную фичу и не боишься сломать что-то в другом углу приложения.

FSD на любой вкус и размер

  • Mini-FSDshared → features → pages. Идеально для стартапов и MVP. Начинайте с этого!
  • Full-FSD — Полный фарш со всеми слоями и строгими правилами. Для зрелых проектов и больших команд.
  • Hybrid-FSD — Постепенное внедрение. Начинали без архитектуры? Постепенно вводите слои.

Не перегружайте проект с самого начала. Начните с мини-версии. Почувствуете, что перерастаете — легко добавите entities и widgets.

Когда FSD — это стрельба из пушки по воробьям

  • Лендинги и промо-сайты на пару страниц.
  • Прототипы, которые живут неделю.
  • Проекты, где вы — единственный разработчик.

Итог: Почему я «болею» FSD

FSD — это не про то, как раскладывать файлы по папкам. Это про архитектурную культуру и дисциплину. Она начинает приносить дивиденды, когда проект выходит из стадии игрушки и превращается в серьёзный продукт.

Она сработает, если:

  • Проекту больше полугода, и он планирует жить дальше.
  • В команде больше двух человек.
  • Вы готовы следить за чистотой импортов и проводить код-ревью.

Она не сработает, если:

  • Внедрять её формально, «для галочки».
  • Игнорировать линтинг.
  • Команда не готова договариваться и соблюдать правила.

Давайте без воды: FSD — это каркас, который делает фронтенд предсказуемым и масштабируемым. Я перевел на него все свои проекты, от маленьких до очень крупных, и результат превзошел все ожидания. Однозначно рекомендую попробовать!


Полезное: