Каждый день мы просыпаемся, завтракаем, идем к компьютеру, садимся и пишем идеальный код, который делает именно то, что мы хотим. А потом мы просыпаемся. Было бы круто, правда? Но это лишь сон.
Насколько бы хорошим кодером вы не были, вы не сможете писать код без багов. Код по определению не может быть без багов. Баг – это та проблема, которую вы не заметили или не ожидали, когда сели писать код. Баг может быть обнаружен только после релиза. Это хуже всего.
Баг можно поймать самому во время тестирования программы. Он даже может возникнуть из-за изменения всего одной строки кода (даже если ранее код работал идеально). Такие баги называют регрессионными.
Баги являются частью нашей повседневной жизни, как разработчиков. Однако наша задача максимально уменьшить их количество. Отлаживать код легко, когда вы умеете бороться с багами.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Как бороться с багами?
Содержание статьи:
Во-первых, постарайтесь избегать их, тщательно продумывая, как ваша программа будет работать. Еще до написания кода. Далее анализируйте каждую строку кода на возможные ошибки и посторонние или неожидаемые эффекты.
Но баги всегда проходят мимо радаров. Никто не вносит баги намеренно. Часто ошибки всплывают только, когда программа уже в проде и используется клиентами.
Вот вы знаете, что есть баг. Как его исправить? Самое сложное – определить место возникновения бага. Когда вы знаете все, что написано выше, решить баг уже достаточно просто.
Обычно для решения бага мы используем 2 способа. Первая техника достаточно базовая – необходимо выяснить значения стейта (переменных) и выполнением программы и вывести эти переменные в лог или в вывод вашей программы.
Локализация ошибки
Отладка – базовый навык для разработчика. Иногда мы делаем все возможное, но программа работает неправильно. Она может вылетать, работать медленно или выводить неверную информацию.
Что делать, если ваша программа ведет себя неправильно? Начать отладку. Первый шаг – понять, что происходит и попробовать определить место, откуда начинается проблема.
Проблема в окружении? Проблема во входных данных? Может, это разовый вылет из-за нехватки памяти? Или проблема воспроизводится постоянно? Все эти вопросы укажут вам направление для решения проблемы.
Зная место в коде, можно приступить к изучению этого куска кода. Самый простой способ отладки с точки зрения инструментов – просто читать свой код вслух. Есть некая магия в том, когда мы проговариваем что-то вслух. Часто я нахожу ошибку именно так. Если не помогло, то пора переходить к инструментам.
Первое знакомство с alert() и console.log()
Если чтение кода не помогло, можно добавить пару строк в свой код. В JavaScript коде фронта вы часто будете использовать alert() и console.log. Разберем код ниже:
JavaScript const a = calculateA() const b = calculateB() const result = a + b
123 | const a = calculateA()const b = calculateB()const result = a + b |
По каким-то неизвестным нам причинам мы получаем неверный результат. Поэтому мы добавим alert(a) и alert(b) перед вычислением результата. В браузере откроется 2 алерт окна при выполнении кода:
JavaScript const a = calculateA() const b = calculateB() alert(a) alert(b) const result = a + b
12345 | const a = calculateA()const b = calculateB()alert(a)alert(b)const result = a + b |
Все работает, если в alert() передавать строку или чисто. Если у вас массивы или объекты, то alert() уже не справится. Вам понадобится console.log():
JavaScript const a = calculateA() const b = calculateB() console.log(a) console.log(b) const result = a + b
12345 | const a = calculateA()const b = calculateB()console.log(a)console.log(b)const result = a + b |
Значения напечатаются в JS консоли браузера в панели разработчика.
Проверка объектов
У нас есть объект car, но мы не знаем, что у него внутри. Но хотим узнать:
JavaScript const car = { color: “black”, manufacturer: “Ford”, model: “Fiesta”, }
12345 | const car = { color: “black”, manufacturer: “Ford”, model: “Fiesta”,} |
Узнать что внутри можно разными способами.
console.log
JavaScript console.log(car)
1 | console.log(car) |
console.dir
JavaScript console.dir(car)
1 | console.dir(car) |
В Node.js можно добавить свойство colors для добавления цветов в терминал:
JavaScript console.dir(car, { colors: true })
1 | console.dir(car, { colors: true }) |
JSON.stringify()
Эта команда распечатает объект как строку:
JavaScript JSON.stringify(car)
1 | JSON.stringify(car) |
Если добавить следующие параметры:
JavaScript JSON.stringify(car, null, 2)
1 | JSON.stringify(car, null, 2) |
Вывод в консоли станет красивее. Последний аргумент определяет чисто отступов:
У JSON.stringify() есть преимущество при вызове не из консоли. Объекты можно выводить на экран.
Перебор свойств в цикле
Вывести в консоль все свойства объекта можно с помощью цикла for…in:
JavaScript const inspect = (obj) => { for (const prop in obj) { if (obj.hasOwnProperty(prop)) { console.log(`${prop}: ${obj[prop]}`) } } } inspect(car)
123456789 | const inspect = (obj) => { for (const prop in obj) { if (obj.hasOwnProperty(prop)) { console.log(`${prop}: ${obj[prop]}`) } }} inspect(car) |
Отладчик браузера
Очень важно уметь дебажить программы, которые работают неправильно. Один из инструментов для поиска багов – отладчик. Отладчик может поставляться сразу с компилятором языка программирования или с дополнительными инструментами.
Например, в Visual Studio Code editor от Microsoft есть JS дебагер. Еще один отладчик есть в браузере.
С помощью отладчика можно остановить программу в любом месте, проверить значения переменных, выполнить любой код и пошагово пройтись по каждой строке.
Если в браузере добавить выражение debugger, это остановит рендер страницы и запустит режим отладки. Отладчик – самый мощный инструмент в панели разработчика в браузере. Его можно найти на вкладке Sources:
Верхняя часть экрана – навигация по файлам. Можно выбрать любой файл и открыть его справа. Очень важно ставить точки остановки. Чуть позже мы разберем их. Нижняя часть это и есть сам отладчик.
Точки остановки
При загрузке страницы браузером JS код выполняется до точки остановки. На этой точке программа останавливается, и вы можете проверить все переменные в программе. Можно проверить значения переменных, а также продолжить пошаговое выполнение программы по одной строке.
Но что такое точка остановки? Простым языком, точка остановки — это инструкция breakpoint, вставленная в ваш код. Когда браузер натыкается на нее, он останавливается.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Неплохой вариант при разработке. Другой способ – открыть файл в панели Sources и кликнуть на номер строки, где хотите добавить точку остановки:
Повторный клик убирает точку. После добавления точки нужно обновить страницу, и код остановится, когда добежит до точки.
После добавления точки остановки ее можно заметить на панели Breakpoints. Видно, что точка остановки стоит в файле form.js на 7 строке. На этой панели отображаются все точки остановки. Их также можно временно отключить.
Есть и другие типы точек остановки:
XHR/fetch брейкпоинты – срабатывают при отправке любых запросов
DOM брейкпоинты – срабатывают при изменении элементов DOM
Слушатели событий – срабатывают при выполнении событий. Например, клик мыши
Область видимости
В этом примере я поставил брейкпоинт внутри слушателя события. Поэтому мне нужно отправить форму, чтобы брейкпоинт сработал:
Все переменные в области видимости отображаются на вкладке Scope. Переменные можно редактировать через двойной клик.
Наблюдение за переменными и выражениями
Справа от Scope есть панель Watch. С помощью кнопки + можно добавить любое выражение. Можно добавить name, и распечатается значение переменной name. Например, значение Flavio. Можно добавить name.toUpperCase(), и выведется FLAVIO:
Продолжить выполнение
Скрипт остановлен, так как код добежал до точки остановки. Над надписью «Paused on breakpoint» есть панель с кнопками, с помощью которых можно менять это состояние.
Первая синяя кнопка продолжит нормальное выполнение скрипта. Вторая — step over – перейти на следующую строку и остановиться. Следующая — step into – проваливается в функции. Step out – делает обратный ход – выходит из вызванной функции. Это основные кнопки для управления отладкой.
Редактирование скриптов
В панели разработчика можно редактировать любой скрипт, даже если скрипт остановлен. Просто отредактируйте файл и нажмите cmd-S на Mac или ctrl-S на Windows/Linux.
Конечно, изменения не сохраняются на диск, если только вы не работаете локально и не настроили рабочее окружение в панели разработчика. Но это уже более продвинутая тема.
Работа со стеком вызовов
В панели call stack можно увидеть, насколько глубоко вы погрузились в JS код. Можно переместиться вверх, если кликнуть на имя функции в стеке:
Печать стек трейса
В некоторых ситуациях полезно распечатать стек трейс вызовов функций. Иногда это помогает ответить на вопрос, как я попал в эту часть кода? Для этого используйте console.trace():
JavaScript const function2 = () => console.trace() const function1 = () => function2() function1()
123 | const function2 = () => console.trace()const function1 = () => function2()function1() |
Логирование ошибок разного уровня
Как мы выше убедились, console.log – классный способ вывода сообщений в консоль. Рассмотрим 3 более удобных метода для дебага. Они подчеркивают различные уровни ошибок.
Первый, console.info()
Перед логом печатается маленькая «i», четко указывающая, что лог просто информативный.
Второй, console.warn()
Печатает желтый восклицательный знак. Если включить тулбар с фильтрами в консоли, то можно заметить, что сообщения можно фильтровать по типу. Фильтровать сообщения действительно удобно. Если мы кликнем на Warnings, все сообщения не относящиеся к предупреждениям будут скрыты.
Третий, console.error()
Этот тип отличается от остальных. Помимо красного Х выводится весь стек трейс функции с ошибкой. И мы можем пойти пофиксить ее.
Сохранение логов при навигации
Сообщения в консоли очищаются при каждом переходе по страницам, если не поставить галку Preserve log в настройках:
Группировка сообщений в консоли
Сообщения в консоли могут становиться все больше и больше, и этот мусор может сбить вас с толку во время отладки.
Дабы решить эту проблему, Console API предлагает полезную функцию – группировка сообщений в консоли. Разберем на примере:
JavaScript console.group(‘Testing the location’) console.log(‘Location hash’, location.hash) console.log(‘Location hostname’, location.hostname) console.log(‘Location protocol’, location.protocol) console.groupEnd()
12345 | console.group(‘Testing the location’)console.log(‘Location hash’, location.hash)console.log(‘Location hostname’, location.hostname)console.log(‘Location protocol’, location.protocol)console.groupEnd() |
Консоль создает группу, внутри которой находятся наши сообщения. Можно сделать то же самое только с закрытой группой, чтобы не засорять лог. Раскрыть группу можно по клику.
JavaScript console.groupCollapsed(‘Testing the location’) console.log(‘Location hash’, location.hash) console.log(‘Location hostname’, location.hostname) console.log(‘Location protocol’, location.protocol) console.groupEnd()
12345 | console.groupCollapsed(‘Testing the location’)console.log(‘Location hash’, location.hash)console.log(‘Location hostname’, location.hostname)console.log(‘Location protocol’, location.protocol)console.groupEnd() |
Группы могут быть вложенными:
JavaScript console.group(‘Main’) console.log(‘Test’) console.group(‘1’) console.log(‘1 text’) console.group(‘1a’) console.log(‘1a text’) console.groupEnd() console.groupCollapsed(‘1b’) console.log(‘1b text’) console.groupEnd() console.groupEnd()
1234567891011 | console.group(‘Main’)console.log(‘Test’)console.group(‘1’)console.log(‘1 text’)console.group(‘1a’)console.log(‘1a text’)console.groupEnd()console.groupCollapsed(‘1b’)console.log(‘1b text’)console.groupEnd()console.groupEnd() |
Blackbox скрипты
Часто приходится работать с библиотеками, где не хочется спускаться в их код. Вы им доверяете и не хотите видеть их код в стек трейсе. Как в примере выше для validator.min.js, который я использую для валидации почты.
Я знаю, что этот скрипт работает как надо. Я могу кликнуть правой кнопкой мыши в стеке вызовов и выбрать Blackbox script. После этого нельзя провалиться в код этого скрипта. И вы можете счастливо работать только над кодом своего приложения.
Панель разработчика в браузере для отладки Node.js
Так как Node.js построен на движке Chrome v8, то можно связать их и использовать Chrome DevTools для дебага Node.js приложений. В терминале выполните команду:
JavaScript node –inspect
1 | node –inspect |
В Chrome перейдите по адресу about://inspect:
Кликните на ссылку Open dedicated DevTools for Node. Это откроет панель разработчика для Node.js.
Нужно кликнуть именно на эту ссылку, а не на inspect ниже. Наш вариант автоматически переподключается к Node.js, когда мы перезапускаем его – очень удобно!
Автор: Flavio Copes
Источник: webformyself.com