|
Отладка (debugging) в JavaScript — это не только console.log(). Современный стек инструментов позволяет находить баги на всех этапах: от написания кода до анализа production-ошибок.
Вот полная классификация методов отладки:
1. Базовые консольные методы (Console API)
Это фундамент. Используйте не только `log`, но и другие уровни:
console.log(), console.info(), console.warn(), console.error() — вывод текста в консоль с разными иконками. console.table() — идеально для массивов объектов (отображает их в виде красивой таблицы). console.trace() — показывает стек-трейс (цепочку вызовов функций) в момент вызова. console.time() / console.timeEnd() — замер времени выполнения участка кода. console.group() / console.groupCollapsed() — группировка логов для читаемости. console.assert() — выводит ошибку в консоль только если условие ложно (отличный способ проверять инварианты).
2. Отладка в браузере (Chrome DevTools, Firefox)
Самый мощный инструмент для frontend-разработки.
• Точки останова (Breakpoints): вкладка Sources -> клик по номеру строки.
- Conditional breakpoint: условная точка останова. Правый клик мышью по номеру строки -> добавить условие (сработает только при `x > 10`). - Logpoint: (или console.log без изменения кода) — ставите точку, но вместо остановки пишете выражение для вывода в консоль.
• Пошаговое выполнение (Stepping): кнопки `Step over` (F10), `Step into` (F11), `Step out`.
• Watch Expressions: панель справа, где можно ввести любое JS-выражение (`user.name.length`) и видеть его значение в реальном времени во время выполнения.
• Blackboxing: скрыть сторонние библиотеки (jQuery, React) от пошаговой отладки, чтобы не прыгать по их внутреннему коду.
3. Отладка асинхронного кода (Async/Await, Promises)
Асинхронность — главная боль в JS.
• Async Stack Traces: в DevTools включено по умолчанию. Позволяет увидеть, где был вызван promise, даже если ошибка произошла через несколько тиков (вкладка Call Stack покажет полную цепочку).
• Асинхронные брейкпоинты: в панели Sources -> раздел `Event Listener Breakpoints` — можно остановить выполнение на клике, таймауте или загрузке DOM-элемента.
4. Отладка серверного кода (Node.js)
• Встроенный инспектор: запуск с флагом `node --inspect-brk app.js`. Затем открываете в Chrome `chrome://inspect` и подключаетесь — получаете полный функционал DevTools для бэкенда.
• Отладка через VS Code: настройка `launch.json`. Вы можете ставить брейкпоинты прямо в редакторе, нажать F5, и код остановится в IDE (без открытия браузера).
• `--trace-warnings`: показывает стек трейсы для предупреждений (например, Unhandled Promise Rejection).
5. Отладка состояния во фреймворках (React/Vue/Angular)
• React DevTools / Vue Devtools: позволяют смотреть `props`, `state` и `hooks` в реальном времени. Можно менять значения на лету и смотреть, как перерисовывается интерфейс.
• Redux DevTools: позволяет "путешествовать во времени" (Time Travel) — отменять и повторять действия (actions), чтобы понять, как менялся state.
6. Обработка ошибок (Error Handling)
• Try...Catch: блокируйте потенциально опасные участки.
• Глобальный перехват:
- В браузере: `window.onerror` и `window.addEventListener('unhandledrejection', ...)`. - В Node.js: `process.on('uncaughtException', ...)`.
• Stack-trace: передавайте в `new Error()` осмысленные сообщения. Используйте `.stack` свойства ошибки для логирования.
7. Продвинутые инструменты (Production)
• Source Maps: обязательно загружайте source maps на сервер (или в Sentry). Без них вы будете видеть ошибки в минифицированном коде (одна строка), а с ними — точное место в вашем исходном файле.
• Sentry / LogRocket / Datadog: инструменты для "отладки продакшена". Они записывают:
- Ошибки с полным стеком. - Скриншот экрана перед ошибкой. - Последовательность действий пользователя (клики, скроллы).
• Feature Flags (Toggles): включайте "режим отладки" на проде для конкретного пользователя, чтобы включить расширенное логирование без передеплоя кода.
8. Отладка производительности (не баги, а тормоза)
• Chrome Performance Tab: запись временной шкалы (FPS, Layout, Paint).
• React Profiler: находит компоненты, которые перерисовываются слишком часто.
• `performance.mark()` и `performance.measure()`: программный замер производительности конкретных участков кода.
9. Инструменты разработчика в IDE (VS Code)
• Встроенный отладчик: позволяет не выходить из редактора.
• Quokka.js: плагин, который показывает результаты выполнения кода прямо рядом со строкой (в real-time), как в Jupyter Notebook — невероятно ускоряет написание простых функций.
Главный совет профессионала: не используйте `console.log` для сложных багов. Научитесь пользоваться брейнкпоинтами (Sources / Node Inspector) — это экономит часы времени, так как вы видите всё состояние приложения, а не только то, что решили вывести в лог.
[Оператор debugger]
debugger; — не просто оператор, это «ручной тормоз» в коде.
Вот всё, что нужно о нём знать:
1. Как это работает
Когда интерпретатор JavaScript встречает ключевое слово debugger;, он принудительно останавливает выполнение кода в этой точке только в том случае, если открыты инструменты разработчика (DevTools).
Если DevTools закрыты, браузер или Node.js просто игнорируют эту строку (она работает как пустышка).
function calculatePrice(items) { let total = 0; for (let item of items) { debugger; // Выполнение остановится здесь на каждой итерации цикла total += item.price * item.quantity; } return total;
}
2. Главное преимущество перед обычным брейкпоинтом
В отличие от клика по номеру строки в интерфейсе DevTools (`Sources`), оператор debugger; живет прямо в исходном коде. Если вы передаете код коллеге или деплоите его на тестовый стенд — остановка сработает у всех, у кого открыты консольные инструменты. Это удобно, когда нужно остановиться строго перед сложным участком, который тяжело найти мышкой в минифицированном коде или в огромном файле.
3. Подводные камни (будьте осторожны!)
Забытые debugger в продакшене — это катастрофа. Если пользователь случайно откроет консоль разработчика (F12), скрипт зависнет на этом месте, и сайт перестанет отвечать на взаимодействие.
Решение1: используйте линтеры (ESLint rule `no-debugger`) и CI/CD, чтобы автоматически отклонять сборку с оператором `debugger`.
Решение2: на этапе сборки (Webpack/Vite) плагины для минификации автоматически удаляют все `debugger;` из продакшен-билда.
В Node.js: если вы запустили `node app.js` (без флага `inspect`), то debugger; просто не сработает. Чтобы он сработал, нужно либо подключить инспектор, либо запустить с флагом `node inspect app.js`.
4. Условный debugger (самый полезный прием)
Вы не можете поставить «условный» брейкпоинт через клик в DevTools так же легко, как в коде. А через debugger — легко:
// Остановит выполнение ТОЛЬКО если пользователь администратор if (user.role === 'admin' && user.actions.includes('delete')) { debugger; // Теперь вы можете в консоли изучить объект user, // не останавливаясь на обычных пользователях
}
5. Как это сочетается с console.log
Хитрый трюк для быстрой отладки без остановки выполнения (альтернатива `console.log`):
// Вместо console.log('user:', user) можно написать: debugger; // Остановка, вы посмотрите user в консоли, // нажмете "Continue" (F8) и побежите дальше.
Это позволяет не захламлять консоль тоннами логов, а получить доступ к полному состоянию приложения (замыканиям, областям видимости) в момент выполнения, чего `console.log` не даёт (он копирует только поверхностные значения).
Итог: debugger; — мощнейший "якорь". Я использую его в 2 случаях:
1. Когда нужно отловить баг, который воспроизводится только после 5 кликов (ставлю `debugger` прямо в обработчике). 2. Вместе с if для отлова "недостижимых" состояний (аналог `console.assert`, но с остановкой). |