0Pricing
Frontend Academy · Урок

Структура каталогов по функциональным возможностям

Организуйте код по предметной области функций, а не по типам, храните тесты, стили и компоненты рядом и устанавливайте границы с помощью eslint-plugin-boundaries

«Структура каталогов по функциональным возможностям» — бесплатный урок Frontend Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.

Два способа организовать код

Код можно группировать по типу (components/, hooks/, services/, types/) или по функциональности (auth/, checkout/, dashboard/ — каждая папка содержит собственные компоненты, хуки и так далее). Для приложений среднего и большого размера лучше подходит группировка по функциональности.

Группировка по типу — классическая ловушка

Классическая структура учебника по React группирует всё по типу. При масштабировании она быстро создаёт проблемы: каждое изменение файла затрагивает несколько несвязанных папок, а чтобы «найти весь код оформления заказа», приходится искать по всему дереву с помощью grep.

// Type-based (avoid for large apps):
src/
  components/
    Button.tsx
    LoginForm.tsx
    CartItem.tsx
  hooks/
    useAuth.ts
    useCart.ts
  services/
    auth.ts
    cart.ts
  types/
    User.ts
    CartItem.ts

Структура по функциональности

Группируйте всё, что относится к одной функциональности, в одной папке. Такой код легко найти, удалить и понять.

src/
  features/
    auth/
      LoginForm.tsx
      SignupForm.tsx
      useAuth.ts
      auth.service.ts
      auth.types.ts
      auth.test.tsx
    cart/
      CartItem.tsx
      CartSummary.tsx
      useCart.ts
      cart.service.ts
      cart.types.ts
  shared/
    components/
      Button.tsx
    hooks/
      useDebounce.ts

Совместное размещение внутри функциональности

Папка функциональности содержит компоненты, хуки, сервисы, типы и тесты — весь код, необходимый для этой предметной области. Нужно понять, как устроена аутентификация? Откройте auth/. Хотите удалить аутентификацию? Удалите папку.

Общий код и код функциональности

Код, используемый двумя и более функциональностями, переносите в shared/ (или lib/). Код, используемый одной функциональностью, оставляйте внутри неё. Не извлекайте код только потому, что «возможно, он пригодится позже»: дождитесь второго использования.

Правила границ функциональностей

Функциональности не должны напрямую импортировать код друг из друга. Если двум функциональностям нужен общий код, вынесите его в shared/. Если им нужно координировать работу, используйте события или общее хранилище на уровне приложения.

Контроль границ с помощью ESLint

Используйте eslint-plugin-boundaries или eslint-plugin-import, чтобы обеспечить правило: функциональности могут импортировать код из shared, но не друг из друга.

// .eslintrc.json
{
  "plugins": ["boundaries"],
  "settings": {
    "boundaries/elements": [
      { "type": "feature", "pattern": "src/features/*" },
      { "type": "shared",  "pattern": "src/shared/*" }
    ]
  },
  "rules": {
    "boundaries/element-types": ["error", {
      "default": "disallow",
      "rules": [
        { "from": "feature", "allow": ["shared"] },
        { "from": "shared",  "allow": ["shared"] }
      ]
    }]
  }
}

Публичный API каждой функциональности

Каждая функциональность экспортирует публичный API через features/auth/index.ts. Остальной код импортирует его из '@/features/auth', а не по глубоким путям. Это позволяет менять внутреннюю реализацию, не нарушая работу потребителей.

// features/auth/index.ts
export { LoginForm } from './LoginForm';
export { useAuth } from './useAuth';
export type { User, AuthState } from './auth.types';

// Consumers:
import { LoginForm, useAuth } from '@/features/auth';
// NOT: import { LoginForm } from '@/features/auth/LoginForm';

Вложенные функциональности

Крупные функциональности могут содержать вложенные папки: dashboard/widgets/, dashboard/charts/. Не углубляйте структуру более чем на 2–3 уровня — поиск станет мучительным.

Где размещать маршруты

Страницы и маршруты можно хранить в папке верхнего уровня pages/ или routes/. Они должны быть тонкими: получать компоненты и хуки из функциональностей и объединять их.

src/
  pages/
    Dashboard.page.tsx   // composes Dashboard widgets from features/dashboard/
    Cart.page.tsx        // composes from features/cart/
  features/
  shared/

Перенос существующего приложения

Начните только с новых функциональностей — помещайте новый код в features/. Не переделывайте всё сразу. По мере работы со старыми файлами постепенно переносите их. Правила границ ESLint предотвращают возврат к прежней структуре.

Когда группировка по типу всё ещё подходит

Для очень небольших приложений (менее 30 компонентов) или библиотек группировка по типу вполне подходит. Переходите к группировке по функциональности, как только появятся отдельные бизнес-области: аутентификация, оформление заказа, платежи и настройки.

Быстрая проверка

Какое главное преимущество с точки зрения организации кода даёт группировка по функциональности вместо группировки по типу файла?

Итоги: структура по функциональности

В features/ находится код, относящийся к конкретным предметным областям; в shared/ — утилиты, используемые разными функциональностями. Каждая функциональность экспортирует публичный index.ts. Функциональности не импортируют код друг из друга — только из shared. Границы контролируются с помощью eslint-plugin-boundaries. Страницы и маршруты объединяют функциональности. Перенос выполняйте постепенно. Для небольших приложений подходит группировка по типу.

Часто задаваемые вопросы

Урок «Структура каталогов по функциональным возможностям» бесплатный?

Да — полный текст урока «Структура каталогов по функциональным возможностям» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.

Чему я научусь в уроке «Структура каталогов по функциональным возможностям»?

Организуйте код по предметной области функций, а не по типам, храните тесты, стили и компоненты рядом и устанавливайте границы с помощью eslint-plugin-boundaries Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Frontend Academy?

Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Структура каталогов по функциональным возможностям»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Frontend Academy?

Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Атомарный дизайн: атомы, молекулы и организмы
  2. Настройка монорепозитория с Turborepo
  3. Микрофронтенды: Module Federation
  4. Структура каталогов по функциональным возможностям
← Назад к Frontend Academy