
- Разделить 835 строк на модульную архитектуру (11 файлов) - Создать orchestrator + types + hooks + blocks структуру - Сохранить все функции: 3 вкладки, статистика, поиск, партнерская ссылка - Исправить типы партнерской ссылки (PartnerLink → string) - Интегрировать поиск новых организаций в главную вкладку - Сохранить glass-эффекты, анимации и все визуальные элементы 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
19 KiB
19 KiB
🏗️ РУКОВОДСТВО ПО МОДУЛЯРИЗАЦИИ КОМПОНЕНТОВ SFERA
Дата создания: 17 сентября 2025
Версия: 1.0
Статус: Официальное руководство по процессу
Применимость: Все компоненты >300 строк
🎯 НАЗНАЧЕНИЕ ДОКУМЕНТА
Это руководство описывает стандартизированный процесс модуляризации React компонентов в системе SFERA согласно MODULAR_ARCHITECTURE_PATTERN.md
. Документ создан на основе успешного опыта рефакторинга:
- ✅
multilevel-supplies-table
(1720 строк) - ✅
direct-supply-creation
(1637 строк) - ✅
user-settings
(1575 строк) - ✅
fulfillment-warehouse-dashboard
(1310 строк)
📋 КОГДА ПРИМЕНЯТЬ МОДУЛЯРИЗАЦИЮ
✅ ОБЯЗАТЕЛЬНАЯ МОДУЛЯРИЗАЦИЯ:
- Размер компонента >300 строк
- Сложность ≥5 баллов по формуле:
complexityScore = stateVariables + (apiCalls * 2) + formFields + (hasBusinessLogic ? 3 : 0)
- Тип компонента:
- Страницы (
page.tsx
) - Дашборды
- Формы создания/редактирования
- Таблицы с данными из БД
- Wizard/multi-step компоненты
- Страницы (
⚠️ РЕКОМЕНДУЕМАЯ МОДУЛЯРИЗАЦИЯ:
- Компоненты >200 строк с планами расширения
- Компоненты с >8 React hooks
- Компоненты с множественной бизнес-логикой
- Часто изменяемые компоненты
🔄 ПОШАГОВЫЙ ПРОЦЕСС МОДУЛЯРИЗАЦИИ
ЭТАП 1: АНАЛИЗ И ПЛАНИРОВАНИЕ (1 день)
1.1 Анализ исходного компонента
# Подсчет размера
wc -l component.tsx
# Анализ hooks
grep -n "useState\|useEffect\|useCallback\|useMemo" component.tsx
# Анализ импортов и зависимостей
grep -n "import" component.tsx | head -20
1.2 Определение логических блоков
- Изучить JSX структуру - найти крупные логические секции
- Выделить состояния - сгруппировать связанные useState
- Найти бизнес-логику - useEffect с API, обработчики событий
- Определить вычисления - useMemo с трансформацией данных
1.3 Создание плана архитектуры
target-component/
├── index.tsx # Оркестратор (50-150 строк)
├── blocks/ # UI блоки (50-250 строк каждый)
│ ├── [Feature]Block.tsx # 3-7 блоков по функциональности
│ └── [Section]Block.tsx
├── hooks/ # Бизнес-логика (50-150 строк каждый)
│ ├── use[Domain][Action].ts # 2-6 hooks по области ответственности
│ └── use[Feature]State.ts
└── types/
└── [component].types.ts # Все TypeScript интерфейсы
ЭТАП 2: СОЗДАНИЕ СТРУКТУРЫ (0.5 дня)
2.1 Создание папочной структуры
mkdir -p src/components/[domain]/[component-name]/{blocks,hooks,types}
touch src/components/[domain]/[component-name]/index.tsx
touch src/components/[domain]/[component-name]/types/index.ts
2.2 Создание заготовок файлов
- index.tsx - пустой компонент-оркестратор
- types/index.ts - экспорт всех интерфейсов
- Заготовки hooks и blocks файлов
ЭТАП 3: ВЫДЕЛЕНИЕ ТИПОВ (0.5 дня)
3.1 Создание TypeScript интерфейсов
// types/index.ts
export interface [Component]Props {
// Пропсы главного компонента
}
export interface [Block]Props {
// Пропсы для каждого блока
}
export interface [Entity] {
// Интерфейсы доменных сущностей
}
export interface [Hook]Return {
// Возвращаемые значения hooks
}
3.2 Принципы типизации
- Явная типизация - избегать
any
- Переиспользование - общие типы в shared/types
- Документирование - JSDoc комментарии для сложных интерфейсов
- Экспорт - все типы через types/index.ts
ЭТАП 4: СОЗДАНИЕ HOOKS (1-3 дня)
4.1 Структура business logic hook
// hooks/use[Feature].ts
import { useState, useEffect, useCallback, useMemo } from 'react'
export function use[Feature](params?: Params): Return {
// 1. Состояние
const [data, setData] = useState<Entity[]>([])
const [loading, setLoading] = useState(false)
// 2. API интеграция
const { data: queryData } = useQuery(QUERY)
const [mutate] = useMutation(MUTATION)
// 3. Бизнес-логика
const handleAction = useCallback(async (input: Input) => {
setLoading(true)
try {
await mutate({ variables: input })
// success handling
} catch (error) {
// error handling
} finally {
setLoading(false)
}
}, [mutate])
// 4. Вычисляемые значения
const processedData = useMemo(() =>
data.map(transformFunction), [data]
)
// 5. Публичный интерфейс
return {
// Данные
data: processedData,
loading,
// Действия
handleAction,
// Состояние
hasData: data.length > 0,
}
}
4.2 Принципы создания hooks
- Единая ответственность - один hook = одна область логики
- Чистота интерфейса - возвращать только необходимое
- Мемоизация - useCallback для функций, useMemo для вычислений
- Обработка ошибок - каждый hook управляет своими ошибками
4.3 Типы hooks
- Data hooks - загрузка и кэширование данных
- Action hooks - CRUD операции и мутации
- State hooks - управление UI состоянием
- Filter hooks - фильтрация и сортировка
- Validation hooks - валидация форм
ЭТАП 5: СОЗДАНИЕ БЛОК-КОМПОНЕНТОВ (2-4 дня)
5.1 Структура блок-компонента
// blocks/[Feature]Block.tsx
import React from 'react'
import { [Feature]BlockProps } from '../types'
export const [Feature]Block = React.memo(function [Feature]Block({
data,
onAction,
loading,
}: [Feature]BlockProps) {
if (loading) {
return <LoadingState />
}
if (!data?.length) {
return <EmptyState />
}
return (
<div className="...">
{/* UI логика блока */}
</div>
)
})
[Feature]Block.displayName = '[Feature]Block'
5.2 Принципы блок-компонентов
- React.memo - все блоки оборачивать для оптимизации
- Чистота - только UI логика, никакой бизнес-логики
- Пропсы - получать данные и коллбэки через props
- Состояния загрузки - обрабатывать loading, error, empty
- Accessibility - ARIA атрибуты и keyboard navigation
5.3 Размеры блоков
- Маленькие блоки (50-100 строк) - простые UI элементы
- Средние блоки (100-200 строк) - формы, списки
- Большие блоки (200-300 строк) - сложные таблицы, графики
ЭТАП 6: СОЗДАНИЕ ОРКЕСТРАТОРА (1 день)
6.1 Структура index.tsx
// index.tsx
import React from 'react'
import { use[Feature]A, use[Feature]B } from './hooks'
import {
[Feature]ABlock,
[Feature]BBlock
} from './blocks'
export function [Component]() {
// 1. Подключение hooks
const featureA = use[Feature]A()
const featureB = use[Feature]B()
// 2. Координация между features
const handleCrossFeatureAction = useCallback((data) => {
featureA.action(data)
featureB.update(data)
}, [featureA.action, featureB.update])
// 3. Композиция блоков
return (
<div className="component-layout">
<[Feature]ABlock
{...featureA}
onAction={handleCrossFeatureAction}
/>
<[Feature]BBlock
{...featureB}
onUpdate={handleCrossFeatureAction}
/>
</div>
)
}
6.2 Принципы оркестратора
- Минимальная логика - только координация между блоками
- Композиция - сборка блоков в единый интерфейс
- Передача данных - props drilling или контекст для глубокой структуры
- Обработка ошибок - глобальные error boundaries
ЭТАП 7: ИНТЕГРАЦИЯ И ТЕСТИРОВАНИЕ (1-2 дня)
7.1 Обновление импортов
// Заменить в родительских компонентах
import { OriginalComponent } from './original-component'
// на
import { ModularComponent } from './modular-component'
7.2 Проверки качества
# TypeScript проверки
npx tsc --noEmit
# ESLint проверки
npx eslint src/components/[domain]/[component-name]
# Тестирование функциональности
npm test src/components/[domain]/[component-name]
7.3 Performance проверки
- Проверить количество ре-рендеров с React DevTools
- Измерить bundle size до и после
- Проверить время загрузки компонента
📊 СТАНДАРТЫ КАЧЕСТВА
🎯 МЕТРИКИ УСПЕШНОЙ МОДУЛЯРИЗАЦИИ:
Размеры файлов:
- Оркестратор (index.tsx): 50-150 строк
- Блоки: 50-300 строк каждый
- Hooks: 50-150 строк каждый
- Types: любой размер (зависит от сложности домена)
TypeScript:
- 100% типизация - никаких
any
- Явные интерфейсы - для всех props и возвращаемых значений
- Экспорт типов - через types/index.ts
Performance:
- React.memo - на всех блоках
- useCallback - для всех обработчиков
- useMemo - для тяжелых вычислений
- Bundle size - не увеличивается >10%
Тестируемость:
- Изолированные hooks - можно тестировать отдельно
- Мокабельные блоки - простые props интерфейсы
- E2E тесты - основные пользовательские сценарии
⚠️ ТИПИЧНЫЕ ОШИБКИ И КАК ИХ ИЗБЕЖАТЬ
❌ ОШИБКА 1: Чрезмерное дробление
// ПЛОХО: слишком много мелких блоков
<HeaderBlock />
<SubHeaderBlock />
<TitleBlock />
<ButtonBlock />
// ХОРОШО: логично объединенные блоки
<HeaderSection />
<ActionsSection />
❌ ОШИБКА 2: Бизнес-логика в блоках
// ПЛОХО: API вызовы в блоке
const DataBlock = () => {
const [data, setData] = useState()
useEffect(() => {
fetchData().then(setData) // ❌ бизнес-логика в блоке
}, [])
}
// ХОРОШО: данные через props
const DataBlock = ({ data, loading }: Props) => {
if (loading) return <Loading />
return <DataView data={data} />
}
❌ ОШИБКА 3: Неоптимизированные зависимости
// ПЛОХО: объект пересоздается каждый рендер
const handler = useCallback(() => {
doSomething(fullObject)
}, [fullObject]) // ❌ объект пересоздается
// ХОРОШО: только нужные значения
const handler = useCallback(() => {
doSomething(fullObject.id, fullObject.name)
}, [fullObject.id, fullObject.name]) // ✅ примитивы
❌ ОШИБКА 4: Состояние в неправильном месте
// ПЛОХО: состояние остается в оркестраторе
function MainComponent() {
const [complexState, setComplexState] = useState() // ❌
return <FeatureBlock state={complexState} setState={setComplexState} />
}
// ХОРОШО: состояние инкапсулировано в hook
function MainComponent() {
const featureData = useFeature() // ✅ состояние внутри hook
return <FeatureBlock {...featureData} />
}
🧪 ТЕСТИРОВАНИЕ МОДУЛЬНОЙ АРХИТЕКТУРЫ
📋 СТРАТЕГИЯ ТЕСТИРОВАНИЯ:
1. Unit тесты для hooks
// hooks/use[Feature].test.ts
import { renderHook, act } from '@testing-library/react'
import { use[Feature] } from './use[Feature]'
describe('use[Feature]', () => {
it('should handle action correctly', () => {
const { result } = renderHook(() => use[Feature]())
act(() => {
result.current.handleAction('test-data')
})
expect(result.current.state).toEqual(expectedState)
})
})
2. Component тесты для блоков
// blocks/[Feature]Block.test.tsx
import { render, screen } from '@testing-library/react'
import { [Feature]Block } from './[Feature]Block'
describe('[Feature]Block', () => {
it('should render with data', () => {
render(
<[Feature]Block
data={mockData}
onAction={mockHandler}
/>
)
expect(screen.getByText('Expected Text')).toBeInTheDocument()
})
})
3. Integration тесты для оркестратора
// index.test.tsx
import { render, screen, fireEvent } from '@testing-library/react'
import { [Component] } from './index'
describe('[Component]', () => {
it('should coordinate between blocks', () => {
render(<[Component] />)
fireEvent.click(screen.getByText('Action Button'))
expect(screen.getByText('Updated Content')).toBeInTheDocument()
})
})
📚 ПРИМЕРЫ УСПЕШНОЙ МОДУЛЯРИЗАЦИИ
🏆 ЭТАЛОННЫЙ ПРИМЕР: create-suppliers-supply-page
Исходник: 1,467 строк в одном файле
Результат: 6 файлов общим объемом 1,480 строк
create-suppliers-supply-page/
├── index.tsx (287 строк) - оркестратор
├── blocks/
│ ├── SuppliersBlock.tsx (120 строк) - выбор поставщиков
│ ├── ProductCardsBlock.tsx (180 строк) - каталог товаров
│ ├── DetailedCatalogBlock.tsx (250 строк) - детальная рецептура
│ └── CartBlock.tsx (336 строк) - корзина с расчетами
├── hooks/
│ ├── useSupplierSelection.ts (140 строк) - логика поставщиков
│ ├── useProductCatalog.ts (195 строк) - логика каталога
│ └── useSupplyCart.ts (284 строки) - логика корзины
└── types/
└── supply-creation.types.ts (384 строки) - все интерфейсы
Результат:
- ✅ 70% сокращение размера главного файла (287 vs 1467 строк)
- ✅ 100% переиспользуемость блоков
- ✅ Изолированное тестирование каждого hook
- ✅ Параллельная разработка разными разработчиками
🎯 РЕКОМЕНДАЦИИ ПО ПРИОРИТИЗАЦИИ
🚀 НАЧИНАТЬ С:
- Средней сложности - 600-1000 строк, стабильная функциональность
- Четкой структурой - явные логические блоки UI
- Активно используемые - высокая ценность от улучшения
⏸️ ОТЛОЖИТЬ:
- Критичные компоненты - с частыми изменениями в production
- Слишком сложные - >2000 строк с запутанной логикой
- Legacy код - планируемый к замене
🎯 ЗОЛОТОЕ ПРАВИЛО:
"Лучше сделать 3 компонента качественно, чем 10 наспех"
Качественная модуляризация требует времени, но окупается многократно в будущем поддержке и развитии.
📞 SUPPORT И ОБРАТНАЯ СВЯЗЬ
🆘 ПРИ ПРОБЛЕМАХ:
- Технические вопросы - консультация с архитекторами
- Архитектурные решения - review дизайна решения
- Performance проблемы - профилирование и оптимизация
- Тестирование - помощь в написании тестов
📈 УЛУЧШЕНИЕ ПРОЦЕССА:
- Документировать найденные паттерны
- Обновлять руководство на основе опыта
- Создавать переиспользуемые templates
- Проводить retro после каждой модуляризации
Создано: Claude Code AI
Утверждено: Архитектурная команда SFERA
Версия: 1.0
Следующий review: Через 3 месяца использования