← Назад к вопросам

В чем разница между модульной архитектурой и FSD?

2.3 Middle🔥 182 комментариев
#JavaScript Core

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В чем разница между модульной архитектурой и FSD?

Модульная архитектура (Module Architecture) и Feature-Sliced Design (FSD) - два популярных подхода к организации кода фронтенда. Оба решают проблему масштабируемости, но работают по разным принципам.

Модульная архитектура

Модульная архитектура группирует файлы по типам (функциональность):

project/
├── components/
│   ├── Button/
│   ├── Modal/
│   ├── Card/
│   └── Header/
├── pages/
│   ├── Home.tsx
│   ├── Profile.tsx
│   └── Settings.tsx
├── hooks/
│   ├── useAuth.ts
│   ├── useApi.ts
│   └── useModal.ts
├── utils/
│   ├── api.ts
│   ├── constants.ts
│   └── helpers.ts
├── types/
│   └── index.ts
└── styles/
    └── globals.css

Характеристики:

  • Файлы группируются по типам (компоненты, хуки, утилиты)
  • Простая структура для небольших проектов
  • Компоненты переиспользуются везде
  • Зависимости "снизу вверх" (utils -> components -> pages)

Feature-Sliced Design (FSD)

FSD группирует файлы по фичам (features), которые содержат всё необходимое:

project/
├── shared/
│   ├── ui/
│   │   ├── Button/
│   │   ├── Modal/
│   │   └── Card/
│   ├── lib/
│   │   ├── api.ts
│   │   └── utils.ts
│   └── types/
│       └── index.ts
├── features/
│   ├── auth/
│   │   ├── ui/
│   │   │   ├── LoginForm/
│   │   │   └── RegisterForm/
│   │   ├── model/
│   │   │   ├── authStore.ts
│   │   │   └── authSlice.ts
│   │   ├── api/
│   │   │   └── authApi.ts
│   │   └── index.ts (public API)
│   ├── profile/
│   │   ├── ui/
│   │   │   └── ProfileCard/
│   │   ├── model/
│   │   │   └── profileStore.ts
│   │   ├── api/
│   │   │   └── profileApi.ts
│   │   └── index.ts
│   └── products/
│       ├── ui/
│       ├── model/
│       ├── api/
│       └── index.ts
├── pages/
│   ├── home/
│   ├── profile/
│   └── not-found/
└── app/
    ├── App.tsx
    ├── layout.tsx
    └── providers.tsx

Характеристики:

  • Файлы организованы по слоям: ui, model (state, logic), api
  • Каждая фича - независимый модуль
  • Слои: shared <- features <- pages <- app
  • Явный public API (index.ts) для каждой фичи
  • Контролируемые зависимости

Основные различия

1. Организация кода

Модульная архитектура (по типам):

components/
  Button.tsx        <- используется везде
  Modal.tsx         <- используется везде
  UserCard.tsx      <- используется везде
  ProductCard.tsx   <- используется везде

FSD (по фичам):

features/
  auth/
    ui/
      LoginForm.tsx     <- только для auth
      RegisterForm.tsx  <- только для auth
  products/
    ui/
      ProductCard.tsx   <- только для products

2. Зависимости

Модульная архитектура - свободные зависимости:

// pages/Home.tsx может зависеть от любого компонента
import { Button, Modal, Card } from '../components';
import { useAuth } from '../hooks';
import { formatDate } from '../utils';
// Сложно отследить, кто от кого зависит

FSD - контролируемые зависимости:

// pages/home/Home.tsx может зависеть только от:
// 1. features/* (через index.ts)
// 2. shared/* (общие компоненты)

import { AuthWidget } from '@/features/auth';
import { ProductList } from '@/features/products';
import { Button } from '@/shared/ui/Button';
// Понятен граф зависимостей

3. Переиспользование компонентов

Модульная архитектура:

// UserCard используется везде
// components/UserCard.tsx
export interface UserCardProps {
  user: User;
  showStats?: boolean;      // для Home
  showActions?: boolean;    // для Admin
  showFollowButton?: boolean; // для Search
  compact?: boolean;        // для Mobile
  // Растет число пропсов...
}

// Компонент становится перегруженным

FSD:

// Разные компоненты для разных фич
// features/profile/ui/UserCard.tsx
export interface UserCardProps {
  user: User;
  showStats: boolean;  // Все пропсы релевантны для этой фичи
}

// features/search/ui/UserCard.tsx
export interface UserCardProps {
  user: User;
  onFollow: () => void;  // Другие пропсы для поиска
}

// Компоненты специализированы

4. Масштабируемость

Модульная архитектура при росте:

components/  <- растет невероятно быстро
  ├── 50+ компонентов
  ├── Сложно ориентироваться
  └── Конфликты в pull requests

hooks/  <- много пересекающейся логики
  └── useUser, useUserForm, useUserEdit, useUserCreate
     <- какой использовать когда?

FSD при росте:

features/
  ├── auth/
  │   ├── ui/        <- 3-5 компонентов
  │   ├── model/
  │   └── api/
  ├── profile/       <- изолированная фича
  └── products/
     <- ясная структура, легко добавлять новые фичи

Практическое сравнение

Сценарий: Добавить новую фичу "Wishlist"

Модульная архитектура:

// 1. Создать компоненты
components/
  WishlistButton.tsx
  WishlistModal.tsx
  WishlistItem.tsx

// 2. Создать хук
hooks/
  useWishlist.ts

// 3. Создать утилиты
utils/
  wishlistApi.ts

// 4. Обновить типы
types/
  index.ts <- добавить Wishlist типы

// 5. Интегрировать везде
pages/
  Home.tsx <- import WishlistButton
  Product.tsx <- import WishlistButton
  Search.tsx <- import WishlistButton

// Проблемы:
// - Файлы разбросаны по папкам
// - Можно неправильно импортировать
// - Вся логика Wishlist разделена

FSD:

// 1. Создать фичу
features/wishlist/
  ui/
    WishlistButton.tsx
    WishlistModal.tsx
    WishlistItem.tsx
  model/
    wishlistStore.ts
    wishlistSlice.ts
  api/
    wishlistApi.ts
  index.ts  <- публичный API

// 2. Интегрировать везде
pages/home/Home.tsx
  import { WishlistButton } from '@/features/wishlist';

pages/product/Product.tsx
  import { WishlistButton } from '@/features/wishlist';

// Преимущества:
// - Вся логика Wishlist в одной папке
// - Понятный импорт из '@/features/wishlist'
// - Легко удалить фичу если не нужна
// - Четкая граница фичи

Сценарий: Переименовать компонент

Модульная архитектура:

// UserCard -> PersonCard
// Нужно найти все импорты

components/UserCard.tsx  // переименовать
pages/Home.tsx
  import { UserCard } from '../components'; // обновить
pages/Profile.tsx
  import { UserCard } from '../components'; // обновить
pages/Search.tsx
  import { UserCard } from '../components'; // обновить
hooks/useUserCard.ts  // переименовать?

// Много мест для ошибки

FSD:

// Если PersonCard специфична для фичи profile
features/profile/ui/PersonCard.tsx

// Одна строка для изменения (index.ts)
features/profile/index.ts
  export { PersonCard } from './ui/PersonCard';

// Все импорты автоматически обновляются
pages/profile/Profile.tsx
  import { PersonCard } from '@/features/profile';
// Не нужно менять, потому что публичный API не изменился

Комбинированный подход

project/
├── shared/              <- FSD слой (модульная архитектура)
│   ├── ui/
│   │   ├── Button/
│   │   └── Modal/
│   ├── lib/
│   │   ├── api.ts
│   │   └── utils.ts
│   └── types/
│
├── features/            <- FSD слой
│   ├── auth/
│   ├── profile/
│   └── products/
│
├── pages/               <- FSD слой
│   ├── home/
│   ├── profile/
│   └── products/
│
└── app/                 <- точка входа
    ├── App.tsx
    └── providers.tsx

// Внутри каждого слоя - модульная архитектура
// features/auth/model содержит authStore.ts, authSlice.ts и т.д.

Когда использовать

Модульная архитектура подходит для:

  • Маленьких проектов (<10 страниц)
  • Прототипов и MVP
  • Проектов с четкой разделением на componets/hooks/utils
  • Когда не ясны границы фич

FSD подходит для:

  • Больших проектов (10+ фич)
  • Долгосрочных проектов
  • Когда нужна масштабируемость
  • Когда работает большая команда
  • Когда есть четкие фичи/домены

Практическая рекомендация

// Гибридный подход
// FSD на макро-уровне (features), модульная на микро-уровне

project/
  shared/
    ├── ui/          <- модульная архитектура
    │   ├── Button/
    │   ├── Modal/
    │   └── Card/
    ├── lib/
    ├── hooks/
    └── types/
  
  features/         <- FSD на макро-уровне
    auth/
      ui/          <- модульная архитектура внутри
      model/
      api/
      hooks/
      types/
      index.ts

// Это лучший баланс между масштабируемостью и простотой

Итоговое сравнение

АспектМодульнаяFSD
ПростотаВышеНиже
МасштабируемостьНизкаяВысокая
Размер проектаМаленькийБольшой
Кривая обученияНизкаяСредняя
ПереиспользованиеМаксимальноеКонтролируемое
ОрганизованностьРазбросаноСтруктурировано
Удаление фичиСложноПросто

Рекомендация: начни с модульной архитектуры, при росте проекта переходи на FSD постепенно.

В чем разница между модульной архитектурой и FSD? | PrepBro