Это перевод статьи Мэтта Деслорьерса — «Debugging Node.js in Chrome DevTools», оригинал которой можно найти у него в блоге по этой ссылке.
Этот пост является введением в новый подход разработки, отладки и профилирования Node.js приложений, используя Chrome DevTools.
devtool
Недавно я работал над консольной утилитой devtool, которая запускает Node.js программы внутри Chrome DevTools.
Запись показывает настройку контрольных точек внутри HTTP-сервера.
Эта утилита построена на Electron, который является смесью возможностей Node.js и Chromium. Эта утилита призвана обеспечить простой интерфейс для отладки, профилирования и разработки Node.js приложений.
Вы можете установить devtool, используя npm:
$ npm install -g devtool
REPL
В некотором смысле, мы можем использовать devtool как замену команде node
в консоли. Для примера, можно открыть REPL вот так:
$ devtool
Это запустит новый экземпляр Chrome DevTools с поддержкой всех возможностей Node.js:
Мы можем подключать модули Node.js, использовать локальные модули и встроенные, как process.cwd()
. Также мы имеем доступ к функциям Chrome DevTools, таким как copy()
и table()
.
Несколько других примеров:
# Запуск скрипта
$ devtool app.js
# Канал контента из файла в process.stdin
$ devtool < audio.mp3
# Канал JavaScript-кода для вычисления
$ browserify index.js | devtool
Разработка
Мы можем использовать devtool
для непрерывной разработки любого модуля и приложения, вместо уже существующих утилит вроде nodemon.
$ devtool app.js --watch
Эта команда запустить ваш app.js
в консоли Chrome DevTools. С помощью флага --watch
мы указываем, чтобы при сохранении файла консоль автоматически перезагружалась.
Кликаем по ссылке app.js:1
, которая приведёт нас на соответствующий файл и строку во вкладке Sources
:
Пока открыта вкладка Sources вы можете использовать клавиатурное сокращение Cmd/Ctrl + P для быстрого поиска необходимого модуля. Вы даже можете инспектировать и отлаживать внутренние модули Node.js. Для просмотра модулей можно использовать левую панель.
Отладка
Так как мы имеем доступ ко вкладке Sources, то мы можем использовать её для отладки нашего приложения. Вы можете установить контрольные точки и затем перезагрузить отладчик (Cmd/Ctrl + R), или вы можете установить начальную контрольную точку с флагом --break
.
$ devtool app.js --break
Ниже представлены несколько функций, которые могут быть сразу не очевидны для тех, кто только начал изучать Chrome DevTools:
Подсказка
Пока отладчик стоит на паузе, вы можете нажать кнопку Escape, чтобы открыть консоль, которая выполняется в текущей области видимости. Вы можете изменить значения переменных, а затем продолжить выполнение.
Профилирование
Другим вариантом применения devtool является профилирование приложений, таких как browserify, gulp и babel.
Здесь мы используем console.profile()
— возможность Chrome для профилирования загрузки CPU сборщиком.
var browserify = require('browserify');
// Начало DevTools профилирования...
console.profile('build');
// Сборка какого-нибудь приложения
browserify('client.js').bundle(function (err, src) {
if (err) throw err;
// Конец DevTools профилирования...
console.profileEnd('build');
});
Теперь мы запустим devtool с нашим файлом:
$ devtool app.js
После выполнения мы можем увидеть результат на вкладке Profiles.
Мы можем использовать ссылки на правой панели для просмотра и отладки горячих путей кода:
Дополнительные параметры
Эксперименты
Chrome постоянно добавляет новые возможности и эксперименты в своём DevTools, такие как инспектор обещаний. Вы можете включить его, нажав три точки в правом верхнем углу и выбрав Settings → Experiments
.
После включения нажмите клавишу Escape, чтобы вызвать инспектор обещаний.
Подсказка
После нажатия Shift 6 раз на странице экспериментов вам откроется больше экспериментальных возможностей, включая и нестабильные.
Флаг --console
Вы можете перенаправить вывод в консоль обратно в терминал (process.stdout
и process.stderr
), что позволяет приукрасить вывод.
$ devtool test.js --console | tap-spec
Флаги --
и process.argv
Выши скрипты могут парсить process.argv
также, как и в обычном Node.js приложении. Если вы передадите что-нибудь после команды полной остановки (--
) в devtool, то оно будет доступно как новый элемент массива process.argv
. Например:
$ devtool script.js --console -- input.txt
Теперь, ваш скрипт может выглядеть так:
var file = process.argv[2];
console.log('Файл: %s', file);
Вывод:
Файл: input.txt
Флаг --quit
и --headless
Флаг --quit
завершает процесс с кодом выхода 1
, когда будет достигнута ошибка (например, ошибка синтаксиса или неперехваченного исключения).
Флаг --headless
позволяет не открывать DevTools при запуске. Это может быть использовано для скриптов командной строки:
$ devtool render.js --quit --headless > result.png
Флаг --browser-field
Некоторые модули могут предоставлять точку входа, которую лучше запустить в браузере. Вы можете использовать флаг --browser-field
для поддержки флагов package.json, когда это требуется модулям.
Например, мы можем использовать xhr-request, который использует технологию XHR, требующую поле "browser"
.
const request = require('xhr-request');
request('https://api.github.com/users/mattdesl/repos', {
json: true
}, (err, data) => {
if (err) throw err;
console.log(data);
});
В терминале:
$ npm install xhr-request --save
$ devtool app.js --browser-field
Теперь мы можем инспектировать запросы на вкладке Network:
Флаг --no-node-timers
По умолчанию мы предоставляем глобальные setTimeout
и setInterval
, которые ведут себя также, как в Node.js, возвращая объект с функциями unred()
и ref()
).
Однако, вы можете отключить их, чтобы улучшить поддержку асинхронной трассировки стека.
$ devtool app.js --no-node-timers
Флаги V8
Вы можете добавить файл .devtoolrc
в текущий каталог, содержащий дополнительные параметры, такие как флаги V8.
{
"v8": {
"flags": [
"--harmony-destructuring"
]
}
}
Смотрите здесь для получения дополнительной информации.
Подводные камни
Так как ваше приложение запускается в окружении браузера (Electron) и не является истинным окружением Node.js, то могут встречаться подводные камни, о которых вы должны быть в курсе.
Сравнение
Уже существуют некоторые отладчики для Node.js, поэтому вам могут быть интересны различия среди них.
WebStorm Debugger
Редактор WebStorm включает в себя весьма хороший отладчик Node.js. Это замечательно, если вы уже используете WebStorm как ваш редактор кода.
Однако, в нем отсутствуют некоторые функции и лоск Chrome DevTools:
- Роскошная и интерактивная консоль
- Пауза на исключениях
- Асинхронные трассировки стека
- Инспектор обещаний
- Профили
Поскольку он интегрируется с вашим рабочим пространством WebStrom, можно вносить изменения и редактировать ваши файлы во время отладки. Также стоит отметить, что он работает в реальном окружении Node/V8, в отличие от devtool, так что это более надежный отладчик для широкого круга Node.js приложений.
iron-node
Это похожий отладчик, основанный на Electron. Он включает в себя встроенную команду перекомпиляции нативных аддонов и сложный графический интерфейс, который показывает ваш package.json
и README.md
.
devtool предоставляет различные возможности Node.js (как require.main
, setTimeout
и process.exit
) и переопределение внутренних механизмов карт исходного кода (source maps), а также имеет улучшенный обработчик ошибок, инъекцию контрольных точек и поле "browser"
.
node-inspector
Вам также может понравиться node-inspector, предлагающий использовать удалённую отладку вместо запуска приложений в окружении Electron.
Это означает, что ваш код будет запущен в настоящем Node.js окружении, без какого-либо window
или другого Browser/Electron API, которое может загрязнять области и вызывать проблемы с некоторыми модулями. Он имеет наиболее полную поддержку больших Node.js приложений (в том числе нативных аддонов) и предоставляет больше контроля над экземпляром DevTools (то есть можно использовать контрольные точки и инспектировать запросы).
Однако, поскольку он повторно реализует большую часть функций отладки, он может быть медленным и неуклюжим, так как часто падает, что приводит к разочарованию среди разработчиков.
В тоже время, devtool старается обеспечить разработчиков уже привычным для них инструментом (Chrome DevTools), а также продвигает другие функции, такие как Browser/Electron API.