Отладка Node.js: от console.log до отладчика

Содержание

О проверке кода. Примеры не запускались в этой сессии (по договорённости — фокус на контенте, а не прогонах). Говорим прямо, а не ставим бейдж «проверено».

Баги неизбежны, и вопрос не «отлаживать ли», а «чем». Многие застревают на console.log и не знают о встроенном отладчике Node.js. Разберём все уровни — от простого к мощному.

Уровень 1: console и его друзья

console.log — не стыдный инструмент, а первая линия. Но у console есть методы удобнее голого log:

console.log(user);                    // обычный вывод
console.table([user1, user2]);        // массив объектов таблицей
console.dir(obj, { depth: null });    // глубокая структура объекта
console.error('ошибка:', err);        // в stderr, не stdout
console.time('запрос');               // замер времени
// ...код...
console.timeEnd('запрос');            // 'запрос: 42ms'

console.log({ user, order, total });  // трюк: имена переменных сохранятся

Трюк console.log({ user, order })сокращённая запись объекта печатает значения вместе с именами, не путаешь, что откуда. console.table незаменим для массивов объектов, console.time — для быстрого замера. Для глубоких объектов лучше util.inspect, который console.log иногда обрезает.

Слабость подхода: на сложном баге расставляешь десять логов, ловишь момент, потом всё убираешь. Для запутанных ошибок есть инструмент лучше.

Уровень 2: встроенный инспектор

node --inspect app.js       # открыть порт отладки
node --inspect-brk app.js   # + остановиться на первой строке

Флаг --inspect запускает Node с открытым портом отладки. К нему подключаются Chrome DevTools: откройте chrome://inspect в браузере — там появится ваш процесс. Дальше — полноценная отладка, как для фронтенда: точки останова, просмотр всех переменных на паузе, пошаговое выполнение, консоль в контексте паузы.

Отладка через инспектор
  1. 1 node –inspect app.jsNode открывает порт отладки 9229
  2. 2 chrome://inspectБраузер находит процесс, жмём inspect
  3. 3 Точка остановаСтавим в коде, исполнение замирает на ней
  4. 4 Смотрим состояниеВсе переменные, стек вызовов, шаг за шагом

--inspect-brk останавливает на первой строке — нужно, когда баг в самом старте приложения и обычный --inspect не успевает подключиться до сбоя.

Ключевое преимущество над console.log: на точке останова видно всё состояние программы разом, без правки кода. Не гадаешь, что залогировать, — смотришь любую переменную по месту.

Уровень 3: отладчик в редакторе

Самый удобный способ — отладка прямо в редакторе, обычно VS Code:

  • откройте панель Run and Debug, создайте конфигурацию для Node;
  • поставьте точку останова кликом слева от номера строки;
  • запустите в режиме отладки — исполнение замрёт на точке;
  • переменные, стек вызовов, watch-выражения видны прямо в редакторе, без переключения окон.

Это то же, что инспектор, но без браузера и с интеграцией в рабочее окружение. Для повседневной отладки — оптимально. Точки останова можно делать условными («остановиться, только если id === 42») — спасает в циклах.

Ключевое слово debugger

function calculate(items) {
  const total = items.reduce((s, i) => s + i.price, 0);
  debugger;             // исполнение остановится здесь (при запуске с --inspect)
  return total * 1.2;
}

Оператор debugger — программная точка останова: при запуске с --inspect исполнение замирает на этой строке. Удобно, когда нужно остановиться в конкретном месте по условию, не кликая в редакторе. В обычном запуске (без инспектора) debugger игнорируется.

Стек вызовов: откуда пришли

function deep() {
  console.log(new Error().stack);   // цепочка вызовов до этого места
}
// или просто бросить — стек будет в сообщении об ошибке

Стек вызовов показывает путь, по которому исполнение дошло до текущего места — кто кого вызвал. В отладчике он виден на паузе; в коде его достают через new Error().stack. Это отвечает на вопрос «откуда вообще вызвалась эта функция с такими аргументами» — частую загадку при отладке.

Что выбрать

Ситуация Инструмент
Быстро глянуть значение console.log / console.table
Замер времени участка console.time
Запутанный баг с состоянием инспектор или VS Code + точки останова
Баг на старте приложения --inspect-brk
«Откуда это вызвано?» стек вызовов
Условная остановка в цикле условная точка останова

Правило: console.log для простого и быстрого, отладчик — как только баг перестаёт быть очевидным. Многие теряют часы на логах там, где точка останова показала бы причину за минуту. Для проблем с памятью и производительностью — отдельные профилировщики в тех же DevTools.


Смежные темы: модуль util — inspect и debuglog; управление памятью — профилирование; REPL — быстрые пробы; логирование. Полный список — в уроках Node.js.

Частые вопросы

Как отлаживать Node.js?
Три уровня: точечный console.log для быстрой проверки значений, встроенный инспектор через флаг –inspect с точками останова в Chrome DevTools, и отладчик в редакторе вроде VS Code. Выбор зависит от сложности проблемы.
Что делает флаг --inspect?
Запускает Node с открытым портом отладки, к которому подключаются Chrome DevTools или редактор. Появляется полноценная отладка: точки останова, просмотр переменных, пошаговое выполнение. Вариант –inspect-brk останавливает исполнение на первой строке.
Чем console.log плох для отладки?
Он годится для быстрой проверки, но при сложных багах приходится расставлять десятки логов, а потом их убирать. Отладчик с точками останова показывает всё состояние программы в момент паузы без правки кода — это эффективнее для запутанных ошибок.
Как отлаживать Node в VS Code?
Открыть панель Run and Debug, создать конфигурацию для Node и запустить файл в режиме отладки. Точки останова ставят кликом слева от номера строки, а переменные и стек вызовов видны прямо в редакторе без переключения окон.
Как посмотреть, откуда вызвана функция?
Через стек вызовов: в отладчике он виден на паузе, а в коде можно бросить ошибку или вывести new Error().stack, чтобы увидеть цепочку вызовов. Стек показывает путь, по которому исполнение дошло до текущего места.