Files
magistr/docs/REACT_MIGRATION_RESULT.md
dipatrik10 97bf3cc50a 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
2026-09-28 23:15:04 +03:00

102 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Итоги миграции 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
```