feat: завершить миграцию фронтенда на React (этапы 1-5)
Админка, настройки, логин, кабинеты преподавателя и студента полностью переведены на React 19 (модель strangler, docs/REACT_MIGRATION.md). - 15 вкладок админки: lazy-загрузка, общий error boundary, сервисный слой - Удалены legacy-views и переходный слой LegacyTabView (45 файлов) - Сборка esbuild (frontend/scripts/build-react.mjs) с бюджетами gzip на чанки - CSP-хэши, кэширование: chunk'и immutable, CSS/HTML no-cache (react-cache.conf) - Фиксы: lazy-импорт именованных экспортов (краш после авторизации), растяжение #admin-root/#settings-root на всю ширину, возврат subjects/lessonTypes из справочников (краш просмотра расписаний), отказ от заведомо широкого поиска расписания без выбранной цели, центрирование карточки логина - Тесты: 237/237 (npm run check), регрессионные на lazy-вкладки и ширину - Документация: REACT_MIGRATION.md, REACT_MIGRATION_RESULT.md, FRONTEND.md
This commit is contained in:
101
docs/REACT_MIGRATION_RESULT.md
Normal file
101
docs/REACT_MIGRATION_RESULT.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Итоги миграции frontend на React
|
||||
|
||||
Дата завершения: 28.09.2026. Полный журнал процесса — в [`REACT_MIGRATION.md`](REACT_MIGRATION.md),
|
||||
архитектура итогового решения — в [`FRONTEND.md`](FRONTEND.md).
|
||||
|
||||
---
|
||||
|
||||
## Что сделано
|
||||
|
||||
По модели strangler (этапы 1–5, все изменения не закоммичены — коммит по решению владельца):
|
||||
|
||||
| Этап | Содержимое | Статус |
|
||||
|------|-----------|--------|
|
||||
| 1. Точка входа и вход в систему | `index.html`, страница логина | Завершён |
|
||||
| 2. Интерфейс студента | SPA `student/` | Завершён |
|
||||
| 3. Интерфейс преподавателя | SPA `teacher/` (пожелания, заявки) | Завершён |
|
||||
| 4. Страница настроек | Отдельный SPA `admin/settings/` (4 вкладки) | Завершён |
|
||||
| 5. Основная админ-панель | Shell + hash-router + **15 вкладок** в 6 волнах | Завершён |
|
||||
|
||||
Волны этапа 5: `dashboard`, `classrooms`, `subjects` → `users`, `groups`, `university-structure` →
|
||||
`teacher-requests`, `department-workspace` → `auditorium-workload`, `academic-calendar` →
|
||||
`schedule-view`, `schedule-versions`, `schedule-quality`, `teacher-absences` → `schedule`
|
||||
(конструктор правил + абсорбция панели разовых правок).
|
||||
|
||||
**Удалено 45 legacy-файлов** (~19 000 строк vanilla-кода): все `admin/js/views/*.js`
|
||||
и `admin/views/*.html`, `admin/js/main.js`, переходный слой `LegacyTabView.jsx` + `legacy-views.js`,
|
||||
дублирующие утилиты `async-combobox.js` и `pagination.js` (заменены общими React-компонентами
|
||||
`AsyncCombobox.jsx` и `Pagination.jsx`).
|
||||
|
||||
**Добавлено 75 React-файлов** (~23 200 строк): оболочки четырёх SPA, 15 вкладок админки,
|
||||
19 сервисов с чистой логикой, общая дизайн-система (`react/shared/ui/`), render-хелперы для тестов.
|
||||
|
||||
---
|
||||
|
||||
## Насколько стало лучше
|
||||
|
||||
### Скорость загрузки и переключения вкладок
|
||||
|
||||
| Метрика (gzip) | До (legacy) | После (React) |
|
||||
|----------------|-------------|---------------|
|
||||
| Переключение вкладки админки | 2 запроса: `fetch` HTML-фрагмента + lazy JS | **1 запрос**: один lazy-chunk |
|
||||
| Средний размер вкладки | HTML + JS отдельно | ~5,1 КБ (128 571 байт / 25 chunk'ов) |
|
||||
| Общие chunk'и (кэшируются между страницами) | — | 79 217 байт (лимит 85 000) |
|
||||
| Холодная загрузка админки | — | 84 857 байт (лимит 90 000) |
|
||||
|
||||
- HTML-фрагменты больше **не загружаются через `fetch`** — вкладка рендерится сразу из
|
||||
одного кэшируемого JS-chunk'а, исчезли двойные сетевые задержки и парсинг HTML на каждое
|
||||
переключение.
|
||||
- Runtime, дизайн-система и утилиты вынесены в общие chunk'и: повторные визиты и переходы
|
||||
между страницами (логин → студент → админка) переиспользуют кэш браузера.
|
||||
- Каждая вкладка загружается отдельно (`React.lazy` + `Suspense`) — пользователь качает
|
||||
только то, что открывает.
|
||||
|
||||
### Качество и надёжность
|
||||
|
||||
- **237 тестов** проходят (`npm run check`), против ~170 на момент начала этапа 5:
|
||||
контракты API, payload-валидация, DOM-рендер каждой вкладки, бюджеты bundle, CSP,
|
||||
разрешение всех lazy-вкладок (регрессия на React error #306 поймана и закрыта тестом).
|
||||
- Логика вынесена в **чистые сервисы** (`*-service.js`) — тестируются в Node без браузера
|
||||
и DOM-заглушек.
|
||||
- Единая дизайн-система вместо копипасты виджетов: кастомные селекты, `AsyncCombobox`,
|
||||
`ConfirmDialog`, `Pagination`, `MaskedDateInput` — одинаковое поведение и a11y везде.
|
||||
- Устранён класс ошибок ручного DOM: React-state вместо `innerHTML`/`classList`,
|
||||
модалки — условный рендер вместо `hidden`-флагов, позиционирование меню — Web Animations API.
|
||||
|
||||
### Безопасность (не ослаблена)
|
||||
|
||||
- CSP-хэши: `[]` — ни одного элемента вне политики.
|
||||
- JWT по-прежнему только в памяти, без inline-скриптов и inline-стилей
|
||||
(проверяется тестами `security-policy.test.mjs`).
|
||||
- Сообщения об ошибках не вставляют текст исключений через `innerHTML`.
|
||||
|
||||
### Сопровождаемость
|
||||
|
||||
- Один стек вместо двух: не нужно поддерживать параллельно vanilla-модули и React.
|
||||
- −19 000 строк legacy-кода, +4 965 строк тестов.
|
||||
- URL/REST-контракты и русский UI сохранены — для пользователей миграция незаметна.
|
||||
|
||||
---
|
||||
|
||||
## Бюджеты bundle (итог, лимиты не поднимались с волны 1)
|
||||
|
||||
| Entry point | Размер gzip | Холодная загрузка | Лимиты |
|
||||
|-------------|-------------|-------------------|--------|
|
||||
| Логин | 2 493 | 81 710 | 10 000 / 85 000 |
|
||||
| Студент | 3 431 | 82 648 | 20 000 / 90 000 |
|
||||
| Преподаватель | 10 145 | 89 362 | 20 000 / 90 000 |
|
||||
| Настройки | 8 466 | 87 683 | 20 000 / 90 000 |
|
||||
| Админ-панель | 5 640 | 84 857 | 20 000 / 90 000 |
|
||||
| Lazy-вкладки админки | 128 571 (25 chunk'ов, по одной за раз) | — | 150 000 |
|
||||
|
||||
---
|
||||
|
||||
## Проверка
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
npm ci
|
||||
npm run build
|
||||
npm run check # 237/237 тестов, бюджеты, CSP
|
||||
```
|
||||
Reference in New Issue
Block a user