
- MODULAR_ARCHITECTURE_PATTERN.md помечен как ОФИЦИАЛЬНЫЙ СТАНДАРТ АРХИТЕКТУРЫ - Добавлены обязательные правила для компонентов >500 строк в новых и >800 строк в существующих - Обновлен CLAUDE.md с автоматической активацией правил архитектуры - Зафиксированы статусы завершенных рефакторингов (create-suppliers-supply-page.tsx, direct-supply-creation.tsx) - Обновлен current-session.md с контекстом архитектурного стандарта 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
334 lines
12 KiB
Markdown
334 lines
12 KiB
Markdown
# 🏗️ Паттерн модульной архитектуры для React компонентов
|
||
|
||
> ⚠️ **ОФИЦИАЛЬНЫЙ СТАНДАРТ АРХИТЕКТУРЫ SFERA**
|
||
> Этот документ описывает **ОБЯЗАТЕЛЬНУЮ** архитектуру для всех новых компонентов >500 строк и рефакторинга существующих >800 строк.
|
||
|
||
## 🎯 СТАТУС АРХИТЕКТУРНОГО СТАНДАРТА
|
||
|
||
### 🟢 ПРИНЯТЫЕ СТАНДАРТЫ (готовы к использованию):
|
||
|
||
- ✅ **create-suppliers-supply-page.tsx** → Модульная архитектура (ФАЗА 1-4 завершены)
|
||
- ✅ **direct-supply-creation.tsx** → Модульная архитектура (ЭТАПЫ 1-5 завершены)
|
||
|
||
### 📋 ПРАВИЛА ПРИМЕНЕНИЯ:
|
||
|
||
1. **ВСЕ НОВЫЕ КОМПОНЕНТЫ >500 строк** → создавать по модульной архитектуре
|
||
2. **Существующие компоненты >800 строк** → рефакторить по возможности
|
||
3. **Обязательно использовать** этот паттерн для компонентов dashboard, creation, management
|
||
|
||
## 🎯 Применимость паттерна
|
||
|
||
### Кандидаты для рефакторинга:
|
||
|
||
- **Размер**: >800 строк кода
|
||
- **Сложность**: Множественные состояния и бизнес-логика
|
||
- **Многообразие UI**: Различные секции интерфейса
|
||
- **Частые изменения**: Активно развивающиеся компоненты
|
||
|
||
### Большие компоненты в SFERA (кандидаты):
|
||
|
||
```
|
||
3052 строки - timesheet-demo.tsx
|
||
2012 строк - fulfillment-warehouse-dashboard.tsx
|
||
1654 строки - navigation-demo.tsx
|
||
1637 строк - direct-supply-creation.tsx ✅ ЗАВЕРШЕН (модульная архитектура)
|
||
1563 строки - user-settings.tsx
|
||
1523 строки - advertising-tab.tsx
|
||
1304 строки - wb-product-cards.tsx
|
||
```
|
||
|
||
## 📁 Универсальная структура модуля
|
||
|
||
```
|
||
src/components/[domain]/[component-name]/
|
||
├── index.tsx # Главный компонент-оркестратор
|
||
├── blocks/ # UI блок-компоненты
|
||
│ ├── [Feature]Block.tsx # Функциональные блоки
|
||
│ ├── [Section]Block.tsx # Секции интерфейса
|
||
│ └── [Action]Block.tsx # Блоки действий
|
||
├── hooks/ # Бизнес-логика
|
||
│ ├── use[Domain][Action].ts # Специфичная логика
|
||
│ ├── use[Entity]Management.ts # CRUD операции
|
||
│ └── use[Feature]State.ts # Управление состоянием
|
||
├── types/ # TypeScript типы
|
||
│ └── index.ts # Все интерфейсы модуля
|
||
└── constants/ # Константы (опционально)
|
||
└── index.ts # Конфигурация и моки
|
||
```
|
||
|
||
## 🔄 Процесс рефакторинга
|
||
|
||
### ЭТАП 1: Анализ и планирование
|
||
|
||
1. **Выделить основные секции UI**
|
||
- Определить логические блоки интерфейса
|
||
- Найти повторяющиеся паттерны
|
||
|
||
2. **Проанализировать состояния**
|
||
- Сгруппировать связанные useState
|
||
- Выделить логику управления состоянием
|
||
|
||
3. **Найти бизнес-логику**
|
||
- useEffect с API вызовами
|
||
- Обработчики форм и событий
|
||
- Вычисляемые значения
|
||
|
||
### ЭТАП 2: Создание типов
|
||
|
||
```typescript
|
||
// types/index.ts
|
||
export interface [Entity] {
|
||
id: string
|
||
// ... поля сущности
|
||
}
|
||
|
||
export interface [Component]Props {
|
||
// ... props компонента
|
||
}
|
||
|
||
export interface [Block]Props {
|
||
// ... props блока
|
||
}
|
||
```
|
||
|
||
### ЭТАП 3: Извлечение hooks
|
||
|
||
```typescript
|
||
// hooks/use[Feature].ts
|
||
export function use[Feature]() {
|
||
const [state, setState] = useState()
|
||
|
||
const handleAction = useCallback(() => {
|
||
// бизнес-логика
|
||
}, [dependencies])
|
||
|
||
return {
|
||
state,
|
||
handleAction,
|
||
// ... другие возвращаемые значения
|
||
}
|
||
}
|
||
```
|
||
|
||
### ЭТАП 4: Создание блок-компонентов
|
||
|
||
```typescript
|
||
// blocks/[Feature]Block.tsx
|
||
export const [Feature]Block = React.memo(function [Feature]Block({
|
||
// ... props
|
||
}: [Feature]BlockProps) {
|
||
return (
|
||
<div className="...">
|
||
{/* UI блока */}
|
||
</div>
|
||
)
|
||
})
|
||
```
|
||
|
||
### ЭТАП 5: Интеграция в главном компоненте
|
||
|
||
```typescript
|
||
// index.tsx
|
||
export function [Component]() {
|
||
// Подключение hooks
|
||
const featureA = useFeatureA()
|
||
const featureB = useFeatureB()
|
||
|
||
// Обработчики с useCallback
|
||
const handleAction = useCallback((data) => {
|
||
// координация между features
|
||
}, [featureA.method, featureB.method])
|
||
|
||
return (
|
||
<div>
|
||
<FeatureABlock {...featureA} onAction={handleAction} />
|
||
<FeatureBBlock {...featureB} onAction={handleAction} />
|
||
</div>
|
||
)
|
||
}
|
||
```
|
||
|
||
## ⚡ Оптимизация производительности
|
||
|
||
### Мемоизация компонентов
|
||
|
||
```typescript
|
||
// Все блоки обернуть в React.memo
|
||
export const MyBlock = React.memo(function MyBlock(props) {
|
||
// ...
|
||
})
|
||
|
||
// Главный компонент: useCallback для обработчиков
|
||
const handleEvent = useCallback(
|
||
(data) => {
|
||
// логика
|
||
},
|
||
[dependency1, dependency2],
|
||
)
|
||
```
|
||
|
||
### Управление ререндерами
|
||
|
||
```typescript
|
||
// В hooks: useMemo для тяжелых вычислений
|
||
const expensiveValue = useMemo(() => {
|
||
return heavyCalculation(data)
|
||
}, [data])
|
||
|
||
// Оптимизация зависимостей useCallback
|
||
const optimizedHandler = useCallback(
|
||
(item) => {
|
||
// вместо передачи всего массива
|
||
// передавать только нужные методы
|
||
},
|
||
[addItem, removeItem],
|
||
) // не [items, addItem, removeItem]
|
||
```
|
||
|
||
## 🧪 Тестирование модульной архитектуры
|
||
|
||
### Unit тесты для hooks
|
||
|
||
```typescript
|
||
import { renderHook, act } from '@testing-library/react'
|
||
import { useFeature } from '../hooks/useFeature'
|
||
|
||
describe('useFeature', () => {
|
||
it('should handle action correctly', () => {
|
||
const { result } = renderHook(() => useFeature())
|
||
|
||
act(() => {
|
||
result.current.handleAction('test')
|
||
})
|
||
|
||
expect(result.current.state).toEqual(expectedState)
|
||
})
|
||
})
|
||
```
|
||
|
||
### Component тесты для блоков
|
||
|
||
```typescript
|
||
import { render, screen } from '@testing-library/react'
|
||
import { FeatureBlock } from '../blocks/FeatureBlock'
|
||
|
||
describe('FeatureBlock', () => {
|
||
it('should render with props', () => {
|
||
render(<FeatureBlock data={mockData} onAction={mockHandler} />)
|
||
expect(screen.getByText('Expected Text')).toBeInTheDocument()
|
||
})
|
||
})
|
||
```
|
||
|
||
## 📊 Метрики успеха рефакторинга
|
||
|
||
### Количественные метрики
|
||
|
||
- **Размер главного файла**: ↓ на 70-85%
|
||
- **Количество модулей**: ↑ в 5-10 раз
|
||
- **Время компиляции**: ↓ на 90%+
|
||
- **Переиспользуемые компоненты**: ↑ с 0 до N
|
||
|
||
### Качественные улучшения
|
||
|
||
- ✅ Читаемость и понимание кода
|
||
- ✅ Простота добавления новых фич
|
||
- ✅ Изолированное тестирование
|
||
- ✅ Переиспользование в других местах
|
||
- ✅ Параллельная разработка команды
|
||
|
||
## 🚨 Частые ошибки и как их избежать
|
||
|
||
### ❌ Чрезмерное дробление
|
||
|
||
```typescript
|
||
// ПЛОХО: слишком много мелких блоков
|
||
<HeaderBlock />
|
||
<SubHeaderBlock />
|
||
<TitleBlock />
|
||
<ButtonBlock />
|
||
|
||
// ХОРОШО: логичные функциональные блоки
|
||
<HeaderSection />
|
||
<ActionsSection />
|
||
```
|
||
|
||
### ❌ Плохие зависимости useCallback
|
||
|
||
```typescript
|
||
// ПЛОХО: передача всего объекта
|
||
const handler = useCallback(() => {
|
||
doSomething(fullObject)
|
||
}, [fullObject]) // объект пересоздается каждый рендер
|
||
|
||
// ХОРОШО: передача только нужных значений
|
||
const handler = useCallback(() => {
|
||
doSomething(fullObject.id, fullObject.name)
|
||
}, [fullObject.id, fullObject.name])
|
||
```
|
||
|
||
### ❌ Неправильное разделение состояния
|
||
|
||
```typescript
|
||
// ПЛОХО: состояние остается в главном компоненте
|
||
function MainComponent() {
|
||
const [complexState, setComplexState] = useState() // управляется извне
|
||
return <FeatureBlock state={complexState} setState={setComplexState} />
|
||
}
|
||
|
||
// ХОРОШО: состояние инкапсулировано в hook
|
||
function MainComponent() {
|
||
const featureData = useFeature() // управляется внутри hook
|
||
return <FeatureBlock {...featureData} />
|
||
}
|
||
```
|
||
|
||
## 📋 Чек-лист рефакторинга
|
||
|
||
### Перед началом
|
||
|
||
- [ ] Компонент больше 800 строк
|
||
- [ ] Есть несколько логических секций UI
|
||
- [ ] Множественные useState и useEffect
|
||
- [ ] Активно развивающийся функционал
|
||
|
||
### Планирование
|
||
|
||
- [ ] Определены основные UI блоки (3-6 штук)
|
||
- [ ] Выделена бизнес-логика для hooks (2-5 штук)
|
||
- [ ] Созданы TypeScript интерфейсы
|
||
- [ ] План поэтапного рефакторинга готов
|
||
|
||
### Реализация
|
||
|
||
- [ ] Создана структура папок
|
||
- [ ] Extracted типы в types/index.ts
|
||
- [ ] Hooks реализованы и протестированы
|
||
- [ ] Блоки созданы с React.memo
|
||
- [ ] Главный компонент интегрирует все части
|
||
- [ ] Старый файл удален
|
||
|
||
### Оптимизация
|
||
|
||
- [ ] Все обработчики используют useCallback
|
||
- [ ] Зависимости useCallback оптимизированы
|
||
- [ ] Тяжелые вычисления в useMemo
|
||
- [ ] Компонент работает без ошибок
|
||
|
||
### Документация
|
||
|
||
- [ ] README для модуля создан
|
||
- [ ] Примеры использования hooks
|
||
- [ ] Документация props для блоков
|
||
- [ ] Архитектурная диаграмма
|
||
|
||
## 🎯 Заключение
|
||
|
||
Модульная архитектура значительно улучшает качество кода, скорость разработки и поддержки. Применяйте этот паттерн к большим компонентам постепенно, следуя принципам безопасного рефакторинга.
|
||
|
||
---
|
||
|
||
**Основано на**: Успешном рефакторинге create-suppliers-supply-page.tsx (1,467→240 строк)
|
||
**Автор паттерна**: Claude Code
|
||
**Дата**: Август 2025
|