Структура проекта
Раздел описывает базовую структуру проекта и принципы организации модулей на уровне папок и файлов.
Базовая структура проекта
Слои FSD не зависят от фреймворка. Различается только содержимое app/ — в React SPA это конфигурация роутинга, в Next.js — системные файлы фреймворка (layout.tsx, page.tsx, route-сегменты).
src/
├── app/ # Инициализация приложения (см. «Слой app/»)
├── screens/ # UI-компоненты страниц
│ └── profile/
│ ├── profile.screen.tsx
│ └── index.ts
├── layouts/ # Общие шаблоны и каркасы страниц
│ └── main-layout/
│ ├── main-layout.layout.tsx
│ └── index.ts
├── widgets/ # Крупные блоки интерфейса
│ └── header/
│ ├── header.widget.tsx
│ └── index.ts
├── features/ # Пользовательские сценарии
│ └── auth-by-email/
│ ├── ui/
│ │ └── login-form.ui.tsx
│ ├── model/
│ │ └── auth-by-email.store.ts
│ ├── auth-by-email.feature.tsx
│ └── index.ts
├── entities/ # Бизнес-сущности
│ └── user/
│ ├── model/
│ │ └── user.store.ts
│ ├── user.entity.tsx
│ └── index.ts
└── shared/ # Общие ресурсы проекта
├── ui/ # Повторно используемые UI-элементы
│ └── icon/
│ ├── styles/
│ │ └── icon.module.css
│ ├── types/
│ │ └── icon.interface.ts
│ ├── icon.ui.tsx
│ └── index.ts
├── lib/ # Утилиты и хелперы
├── services/ # Общие сервисы и клиенты
├── config/ # Общие конфигурации и константы
└── assets/ # Ресурсы
├── images/
├── icons/
├── fonts/
└── video/Слой app/
Общее для обоих вариантов: провайдеры и глобальные стили. Различается только способ организации роутинга.
React SPA
src/app/
├── providers/ # Провайдеры и обёртки приложения
├── routing/ # Конфигурация маршрутов (React Router)
├── styles/ # Глобальные стили, CSS-переменные, custom media
└── index.ts # Entry point приложенияNext.js (App Router)
src/app/
├── providers/ # Провайдеры и обёртки приложения
├── styles/ # Глобальные стили, CSS-переменные, custom media
├── layout.tsx # Корневой layout (подключает providers, styles)
├── page.tsx # Главная страница
└── profile/
└── page.tsx # Рендерит ProfileScreenВ Next.js файлы page.tsx остаются тонкими — они только импортируют экран из screens/ и рендерят его. Вся логика, зависимости и стили страницы живут в компоненте экрана, а не в app/.
// src/app/profile/page.tsx
import { ProfileScreen } from '@/screens/profile';
export default function ProfilePage() {
return <ProfileScreen />;
}Плохо
// Плохо: слои смешаны, нет понятных границ и публичного API.
src/
├── components/
├── api/
├── styles/
└── user.tsПравила организации
В слоях FSD (
features,entities,widgets,screensи т.д.)ui/используется только для дочерних элементов, которые относятся к модулю и не экспортируются отдельно. Главные компоненты, которые составляют сам слой, держат собственные*.feature.tsx,*.widget.tsxи т. п., аui/служит для вспомогательных мелких компонентов.В
shared/ui/хранятся базовые UI-элементы/компоненты, которыми пользуются сразу несколько модулей; в этом случае они экспортируются наружу и не считаются «дочерними» для слоя.Если модуль строится вокруг «главного» компонента (
*.feature.tsx,*.screen.tsx,*.widget.tsx), помещайте его в корень модуля и экспортируйте черезindex.ts. Проверяйте, чтоui/не используется просто как «контейнер» слоя.Каждый слой и модуль хранится в собственной папке.
Внутренние реализации разделяются на
ui/,model/,styles/,helpers/,lib/,api/.Публичный API модуля объявляется в
index.ts.Внутренние файлы не импортируются напрямую извне.
Не смешивать ответственность разных слоёв в одном модуле.