Будешь ли организовывать проект с Next.js с нуля на FSD

Ответ

Да, FSD (Feature-Sliced Design) отлично подходит для Next.js. Вот как я бы организовал структуру:

src/
├── app/                # Next.js 13+ app router
├── pages/              # (опционально) для pages router
├── features/           # фичи (авторизация, профиль и т.д.)
│   ├── auth/           # пример фичи
│   │   ├── api/        # API-логика
│   │   ├── ui/         # UI компоненты
│   │   └── model/      # бизнес-логика
├── entities/           # сущности (User, Product)
├── widgets/            # сложные UI-блоки
├── shared/             # переиспользуемый код
│   ├── ui/             # UI-кит (кнопки, инпуты)
│   ├── lib/            # утилиты/хелперы
│   └── api/            # базовые API-настройки
└── styles/             # глобальные стили

Ключевые моменты:

  • Разделение по бизнес-логике, а не по типам файлов
  • features/ содержит полноценные фичи с собственной логикой
  • entities/ для независимых бизнес-сущностей
  • shared/ для переиспользуемого кода

Пример фичи авторизации:

// features/auth/ui/LoginForm.tsx
export const LoginForm = () => {
  const { login } = useAuth(); // из features/auth/model
  return <form onSubmit={login}>...</form>;
}

Такой подход улучшает масштабируемость и изолирует изменения.

Ответ 18+ 🔞

О, смотри-ка, народ опять за FSD взялся, как будто это панацея от всех бед! Ну ладно, раз уж спросили — сейчас разложу по полочкам, как это в Next.js впихнуть, чтобы потом не орать «ёбаный в рот, кто так структуру проекта делал?!».

Вот, блядь, смотри, как я бы это сверстал:

src/
├── app/                # Это Next.js 13+ со своим app router, его не трогаем, он священная корова
├── pages/              # На всякий пожарный, если вдруг старый router нужен (но лучше не надо)
├── features/           # А вот тут, сука, самое интересное — фичи наши
│   ├── auth/           # Ну, типа, авторизация, логины-пароли, вся эта хуйня
│   │   ├── api/        # Тут API-шники, которые с бэком общаются
│   │   ├── ui/         # Интерфейсы, формы, кнопочки — всё, что юзер тыкает
│   │   └── model/      # А здесь, блядь, мозги! Бизнес-логика, хуки, стейт
├── entities/           # Сущности, которые сами по себе гуляют: User, Product, Cart — понимаешь?
├── widgets/            # Сложные UI-шные блоки, которые из кучи компонентов собраны
├── shared/             # Общедоступное барахло, которое везде таскают
│   ├── ui/             # Кнопки, инпуты, попапы — чтоб десять раз не изобретать
│   ├── lib/            # Утилиты, хелперы, константы — скукота, но без них никуда
│   └── api/            # Настройки axios, instance, interceptors — чтоб не копипастить
└── styles/             # Глобальные стили, переменные, reset.css — чтоб не было «ой, а почему шрифт съехал?»

Смысл-то в чём, а? В том, чтобы не валить всё в одну кучу, как свинья в апельсинах! Разделяем по смыслу, а не по типам файлов. Фича — это как отдельный модуль, который живёт своей жизнью. Захотел авторизацию переделать — пошёл в features/auth и там всё нашёл, а не бегай по всему проекту, как угорелый.

Вот, смотри, как это в коде выглядит, на примере этой самой авторизации:

// features/auth/ui/LoginForm.tsx
export const LoginForm = () => {
  const { login } = useAuth(); // Это, блядь, из features/auth/model тянем
  return <form onSubmit={login}>...</form>;
}

Видишь? Всё на своих местах: UI-компонент в ui/, логика в model/. Ничего никуда не расползается. И если завтра тебе понадобится форму регистрации добавить — ты её рядом, в той же фиче, создаёшь, а не в components/ какой-то общей свалке.

Такой подход, конечно, не серебряная пуля, но хотя бы даёт шанс, что через полгода ты в своём же коде не запутаешься, как мартышка в гранатах. Масштабируется нормально, изменения изолированы — красота, да и только! Главное — придерживайся, а то опять получится «пиздопроебибна архитектура», которую только переписывать.