Что должно быть в features в контексте FSD?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Features в FSD (Feature Sliced Design)
FSD — это методология архитектуры, которая организует код по функциональным слайсам. Папка features/ содержит самостоятельные, переиспользуемые функциональные модули, каждый из которых отвечает за одну пользовательскую возможность.
Что должно быть в features
Features — это набор функций, которые пользователь может взаимодействовать. Каждый feature — это независимый модуль с полным набором слоев архитектуры.
Структура одного feature
features/
├── auth/ # Feature: аутентификация
│ ├── ui/ # UI компоненты (представление)
│ │ ├── LoginForm.tsx
│ │ └── LoginForm.test.tsx
│ ├── model/ # Бизнес-логика и состояние
│ │ ├── authSlice.ts
│ │ ├── selectors.ts
│ │ └── types.ts
│ ├── api/ # Взаимодействие с backend
│ │ └── loginAPI.ts
│ ├── lib/ # Утилиты feature-специфичные
│ │ └── validateEmail.ts
│ └── index.ts # Public API feature
│
├── comments/ # Feature: комментарии
│ ├── ui/
│ │ ├── CommentList.tsx
│ │ ├── CommentItem.tsx
│ │ └── CommentForm.tsx
│ ├── model/
│ │ ├── commentsSlice.ts
│ │ ├── selectors.ts
│ │ └── types.ts
│ ├── api/
│ │ └── commentsAPI.ts
│ └── index.ts
│
└── notifications/ # Feature: уведомления
├── ui/
│ └── NotificationToast.tsx
├── model/
│ └── notificationsSlice.ts
└── index.ts
Слои внутри feature
1. UI слой — компоненты для отображения
- Чистые, переиспользуемые компоненты React
- Принимают данные и callbacks через props
- Не зависят от Redux/состояния
// ui/LoginForm.tsx
export const LoginForm: React.FC<LoginFormProps> = ({ onSubmit, isLoading }) => {
const [email, setEmail] = useState();
// ...
return <form>...</form>;
};
2. Model слой — управление состоянием
- Redux slices, store configuration
- Селекторы для доступа к состоянию
- Типы (interfaces, types)
// model/authSlice.ts
const authSlice = createSlice({
name: auth,
initialState: { user: null, loading: false },
reducers: { /* ... */ },
});
export const selectUser = (state) => state.auth.user;
3. API слой — запросы к серверу
- Функции для HTTP запросов
- Трансформация данных
- Обработка ошибок
// api/loginAPI.ts
export const loginAPI = async (email: string, password: string) => {
const response = await fetch(/api/v1/auth/login, {
method: POST,
body: JSON.stringify({ email, password }),
});
return response.json();
};
4. Lib слой — вспомогательные утилиты
- Функции-helpers
- Валидация
- Трансформация данных (не API)
// lib/validateEmail.ts
export const isValidEmail = (email: string): boolean => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
};
5. Index (Public API) — экспорт для остального кода
// index.ts
export { LoginForm } from ./ui;
export { authSlice, selectUser } from ./model;
export { loginAPI } from ./api;
export { isValidEmail } from ./lib;
Правила использования features
1. Иерархия зависимостей:
ui → model → api → lib
UI может использовать model, api и lib. Model может использовать api и lib. API только использует lib.
2. Изоляция features Features не должны импортировать друг друга напрямую:
// ❌ Плохо
import { LoginForm } from @/features/auth;
// ✅ Хорошо — использовать через index.ts
import { LoginForm } from @/features/auth;
3. Переиспользуемость Feature должен быть независимым модулем, который можно использовать в разных местах приложения.
Что НЕ должно быть в features
- Глобальное состояние приложения (в store/)
- Макеты страниц (в pages/)
- Переиспользуемые компоненты без бизнес-логики (в shared/)
- Конфигурация приложения (в app/)
Пример использования feature
// pages/login.tsx
import { LoginForm, loginAPI } from @/features/auth;
import { useAppDispatch } from @/store;
export default function LoginPage() {
const dispatch = useAppDispatch();
const handleLogin = async (email: string, password: string) => {
try {
const result = await loginAPI(email, password);
dispatch(setUser(result.user));
} catch (error) {
// обработка ошибки
}
};
return <LoginForm onSubmit={handleLogin} />;
}
Преимущества FSD для features
- Модульность — легко добавлять/удалять функции
- Переиспользуемость — один feature можно использовать в разных модулях
- Масштабируемость — при росте проекта структура остаётся понятной
- Тестирование — каждый feature можно тестировать независимо
- Командная работа — разные разработчики могут работать на разных features без конфликтов