Code Review: лучшие практики
Code Review — процесс проверки кода другими разработчиками перед слиянием. Как давать ревью, как принимать, чеклист проверки и типичные ошибки.
Зачем нужен Code Review
Code Review (ревью кода) — проверка изменений другим разработчиком перед тем, как код попадёт в основную ветку. Это не формальность, а рабочий инструмент: ревью ловит баги, поддерживает стиль, распространяет знания и помогает всей команде расти.
Google в исследовании обнаружил, что Code Review находить баги на 15-20% чаще, чем одного тестирования. А ещё это лучший способ познакомить нового разработчика с кодовой базой — через его PR и через ревью чужих.
Как автору подготовить PR
Один PR — одна задача
❌ Плохо: PR «Добавил поиск, починил баг с логином, обновил README»
✅ Хорошо: PR «feat: добавил поиск задач с debounce и фильтрацией»
Маленькие PR ревьют лучше. Идеальный размер — до 400 строк. Больше 800 — почти никто не читает внимательно. Если задача большая, разбейте на несколько PR:
PR #1: feat: add search API service
PR #2: feat: add search input component with debounce
PR #3: feat: integrate search into task list page
Понятное описание
## Что сделано
Добавлен поиск задач с автодополнением и debounce 300ms.
## Как проверить
1. Открыть /tasks
2. Начать вводить в поле поиска
3. Убедиться, что результаты фильтруются
## Скриншот
[скриншот UI]
## Связанная задача
Closes #42
Перед отправкой на ревью
# Убедиться, что CI проходит
npm run lint
npm run test
npm run build
# Проверить, что нет случайных изменений
git diff main...HEAD --stat
# Найти забытыые console.log и debugger
git diff main...HEAD | grep -E "console\.|debugger"
Само-ревью
Перед добавлением ревьюеров просмотрите свой PR самостоятельно. Пройдитесь по диффу — часто находятся опечатки, забытые импорты или лишние изменения. Это экономит время ревьюера.
Как ревьюить
Порядок чтения
- Описание PR — понять контекст и цель
- Файлы по степени важности — сначала бизнес-логика, потом тесты, в конце стили
- Тесты — покрывают ли они логику, есть ли edge cases
Категории замечаний
Используйте префиксы, чтобы автор понимал серьёзность:
| Префикс | Значение | Пример |
|---|---|---|
[block] | Блокирует мерж | [block] SQL-инъекция в строке 42 |
[issue] | Нужно исправить | [issue] Нет обработки ошибки 404 |
[suggestion] | Предложение | [suggestion] Можно использовать computed() здесь |
[nitpick] | Мелкое замечание | [nitpick] Лишняя пустая строка |
[question] | Вопрос для понимания | [question] Зачем этот эффект в ngOnInit? |
[praise] | Хороший код | [praise] Отличная абстракция, забрал себе |
Что НЕ должен проверять ревьюер
| Что | Кто это ловит |
|---|---|
| Отступы и пробелы | Prettier |
| Отсутствие типов | TypeScript |
| Имена переменных | ESLint (если настроены правила) |
| Несовпадение стиля | ESLint + Prettier |
| Прохождение тестов | CI |
Что ДОЛЖЕН проверять ревьюер:
- Правильность логики
- Архитектурные решения
- Обработка ошибок и edge cases
- Читаемость и поддерживаемость
- Достаточность тестов
Чеклист ревьюера
Корректность
- Код делает то, что описано в PR
- Обрабатываются ошибки (try/catch, catchError, error states)
- Нет edge cases: пустой массив, null, undefined, пустая строка
- Условия корректны (=== вместо ==, правильные операторы)
- Циклы не зависят при пустых данных
Безопасность
- Нет
innerHTMLбез санитизации - Нет захардкоженных токенов, паролей, ключей
- Пользовательский input экранируется
- API-запросы используют авторизацию
Производительность
- Нет ненужных перерендеров (OnPush, memo, trackBy)
- Тяжёлые вычисления мемоизированы (computed, useMemo)
- Нет утечек памяти (отписки от Observable, removeEventListener)
- Большие списки используют virtual scrolling или пагинацию
Архитектура
- Нет дублирования кода (DRY)
- Компонент/функция делает одну вещь (SRP)
- Нет лишней связанности между модулями
- Паттерны проекта соблюдены
Тесты
- Новая логика покрыта тестами
- Тестируются негативные сценарии (ошибки)
- Нет тестов ради тестов (assert true === true)
Как давать фидбек
Плохо vs Хорошо
❌ «Это ужасный код»
✅ «Здесь используется мутация state напрямую — это может привести к багам. Лучше return [...items, newItem]»
❌ «Переделай нормально»
✅ «Предлагаю вынести валидацию в отдельную функцию — будет проще тестировать и переиспользовать»
Правила
- Критикуй код, не человека — «этот подход может вызвать проблемы» вместо «ты написал плохо»
- Объясняй почему — не «исправь», а «исправь, потому что при пустом массиве будет ошибка»
- Предлагай альтернативу — не просто указывай на проблему, а показывай решение
- Хвали хорошее — замечания запоминаются, а похвала мотивирует
Как автору реагировать на замечания
| Реакция | Когда |
|---|---|
| Исправить и запушить | Согласны с замечанием |
| Ответить объяснением | Есть причина, почему сделано так |
| Обсудить в комментариях | Не уверены — обсудите |
| Дискуссия в чате/звонке | 5+ комментариев в одном месте |
Не принимайте замечания лично. Ревью кода, а не вас.
Процесс в команде
Сроки
- Ревью — в течение 24 часов
- Автор отвечает — в течение 24 часов
- PR не висит больше 2 дней без прогресса
CODEOWNERS
GitHub позволяет назначить обязательных ревьюеров для частей кодовой базы:
# .github/CODEOWNERS
/src/app/auth/ @team-backend
/src/app/shared/ @senior-devs
/package.json @tech-lead
Файлы в /src/app/auth/ не смёржатся без аппрува от @team-backend.
Размер PR и качество
| Строк | Качество ревью | Рекомендация |
|---|---|---|
| до 100 | Отличное | Идеальный размер |
| 100-400 | Хорошее | Нормально |
| 400-800 | Среднее | Стоит разбить |
| 800+ | Плохое | Обязательно разбить |
Итог
| Совет | Для кого |
|---|---|
| PR до 400 строк | Автор |
| Понятное описание + скриншот | Автор |
| Прогнать lint + test перед отправкой | Автор |
| Префиксы nitpick, issue, block | Ревьюер |
| Чеклист: корректность, безопасность, производительность | Ревьюер |
| Критикуй код, не человека | Ревьюер |
| Автоматизировать стиль через ESLint/Prettier | Команда |
| CODEOWNERS для обязательных ревьюеров | Команда |
Code Review — не бюрократия, а инструмент. Хорошо отревьюенный PR экономит часы отладки на продакшене. И чем качественнее автор подготовил PR — тем полезнее будет ревью.