Отладка JavaScript не самый интересный аспект программирования на JavaScript, но это жизненно важный навык. В этой статье рассматриваются два инструмента, которые помогут вам отладить JavaScript как профессионал.
Представьте на мгновение, что функция console.log()
не существует в JavaScript. Я уверен, что первый вопрос, который вы себе зададите, будет: «Как я смогу убедиться, что мой код работает правильно?»
Ответ заключается в использовании инструментов отладки. В течение долгого времени большинство разработчиков, включая меня, использовали console.log
для отладки неработающего кода. Это быстрый и простой в использовании. Тем не менее, иногда вещи могут становиться привередливыми, если вы не знаете, где и что является причиной ошибки. Часто вы обнаруживаете, что расставляете ловушки console.log
всему коду, чтобы увидеть, какой из них выявит виновника.
Чтобы исправить это, нам нужно изменить свои привычки и начать использовать инструменты отладки. Для отладки кода JavaScript доступно множество инструментов, таких как Chrome Dev Tools, Node Debugger , Node Inspect и другие. Фактически, каждый крупный браузер предоставляет свои собственные инструменты.
В этой статье мы рассмотрим, как использовать средства отладки, предоставляемые Visual Studio Code. Мы также рассмотрим, как использовать расширение Debugger for Chrome, которое позволяет интегрировать VS Code с Chrome Dev Tools. Когда мы закончим, вы больше никогда не захотите использовать console.log()
.
Предпосылки
Для этого урока вам нужно только иметь прочную основу в современном JavaScript . Мы также посмотрим, как мы можем отладить тест, написанный с использованием Mocha и Chai . Мы будем использовать неработающий проект, пример отладки , чтобы научиться исправлять различные ошибки без использования единого console.log
. Вам понадобится следующее:
Начните с клонирования проекта -примера отладки в вашу рабочую область. Откройте проект в VS Code и установите зависимости через встроенный терминал:
# Install package dependencies npm install # Install global dependencies npm install -g mocha
Теперь мы готовы научиться отлаживать проект JavaScript в VS Code.
Отладка JavaScript в VS Code
Первый файл, на который я хотел бы взглянуть, это src/places.js
. Вам нужно открыть папку debug-project
в VS Code ( Файл > Открыть папку ) и выбрать файл в редакторе.
const places = []; module.exports = { places, addPlace: (city, country) => { const id = ++places.length; let numType = 'odd'; if (id % 2) { numType = 'even'; } places.push({ id, city, country, numType, }); }, };
Код довольно прост, и если у вас достаточно опыта в кодировании, вы можете заметить, что в нем есть пара ошибок. Если вы заметили их, пожалуйста, игнорируйте их. Если нет, отлично. Давайте добавим несколько строк внизу, чтобы вручную проверить код:
module.exports.addPlace('Mombasa', 'Kenya'); module.exports.addPlace('Kingston', 'Jamaica'); module.exports.addPlace('Cape Town', 'South Africa');
Теперь я уверен, что вам не терпится сделать console.log
для вывода значения places
. Но давайте не будем этого делать. Вместо этого давайте добавим точки останова . Просто добавьте их, щелкнув левой кнопкой мыши по желобу — то есть пустое пространство рядом с номерами строк:
Видите красные точки на стороне? Это точки останова. Точка останова — это просто визуальная индикация, указывающая инструменту отладчика, где приостановить выполнение. Затем на панели действий нажмите кнопку отладки (значок с надписью «Ошибки не разрешены»).
Посмотрите на верхний раздел. Вы заметите значок шестеренки с красной точкой. Просто нажмите на него. Файл конфигурации отладки, launch.json
, будет создан для вас. Обновите конфигурацию следующим образом, чтобы вы могли запустить отладчик VS Code на places.js
:
"configurations": [ { "type": "node", "request": "launch", "name": "Launch Places", "program": "${workspaceFolder}\\src\\places.js" } ]
Примечание. В зависимости от операционной системы вам может потребоваться заменить двойную обратную косую черту ( \\
) на одну прямую косую черту ( /
).
После сохранения файла вы увидите, что на панели отладки появился новый раскрывающийся список « Места запуска» . Чтобы запустить его, вы можете:
- нажмите зеленую кнопку Play на панели отладки
- нажмите F5
- нажмите Отладка > Начать отладку в строке меню.
Используйте любой метод, который вам нравится, и наблюдайте за процессом отладки в действии:
Ряд вещей происходит в быстрой последовательности, когда вы нажимаете кнопку отладки. Во-первых, есть панель инструментов, которая появляется в верхней части редактора. Имеет следующие элементы управления:
- Drag Dots anchor : для перемещения панели инструментов туда, где она ничего не блокирует
- Продолжить : продолжить сеанс отладки
- Шаг за шагом : выполнение кода построчно, пропуская функции
- Шаг в : выполнение кода построчно, входя в функции
- Выход : если уже внутри функции, эта команда выведет вас
- Restart : перезапускает сеанс отладки
- Стоп : останавливает сеанс отладки.
Прямо сейчас вы заметите, что сеанс отладки остановился на вашей первой точке останова. Чтобы продолжить сеанс, просто нажмите кнопку « Продолжить» , что приведет к продолжению выполнения до достижения второй точки останова и повторной паузы. Повторное нажатие кнопки Continue завершит выполнение, и сеанс отладки будет завершен.
Давайте начнем процесс отладки снова, нажав F5 . Убедитесь, что две точки останова все еще на месте. Когда вы устанавливаете точку останова, код останавливается на указанной строке. Эта строка не выполняется, если вы не нажмете « Продолжить» ( F5 ) или « Перешагните» ( F10 ). Прежде чем вы нажмете что-нибудь, давайте посмотрим на разделы, которые составляют панель отладки:
- Переменные : отображает локальные и глобальные переменные в текущей области (т. Е. В точке выполнения)
- Смотрите : вы можете вручную добавить выражения переменных, которые вы хотите отслеживать
- Стек вызовов : отображает стек вызовов выделенного кода
- Точки останова : отображает список файлов с точками останова вместе с их номерами строк.
Чтобы добавить выражение в раздел « Watch », просто нажмите знак « +» и добавьте любое допустимое выражение JavaScript — например, places.length
. Когда отладчик делает паузу, если ваше выражение находится в области видимости, значение будет напечатано. Вы также можете навести курсор на переменные, которые в настоящее время находятся в области видимости. Появится всплывающее окно с отображением их значений.
В настоящее время массив places
пуст. Нажмите любой элемент управления навигацией, чтобы увидеть, как работает отладка. Например, Step over перейдет к следующей строке, а Step into перейдет к функции addPlace
. Потратьте немного времени, чтобы ознакомиться с элементами управления.
Как только вы сделаете шаг, наведите курсор на переменную places
. Появится всплывающее окно. Расширяйте значения внутри, пока у вас не появится похожее представление:
Вы также можете проверить все переменные, находящиеся в области действия, в разделе « Переменные ».
Это довольно круто по сравнению с тем, что мы обычно делаем с console.log
. Отладчик позволяет нам проверять переменные на более глубоком уровне. Возможно, вы также заметили пару проблем с выводом массива places
:
- в массиве несколько пробелов, то есть
places[0]
иplaces[2]
неundefined
- свойство
numType
отображаетсяeven
для нечетных значенийid
.
А пока просто завершите сеанс отладки. Мы исправим их в следующем разделе.
Отладка тестов с Mocha
Откройте test/placesTest.js
и просмотрите код, написанный для проверки кода в places.test
. Если вы никогда раньше не использовали Mocha, вам нужно сначала установить его глобально, чтобы запустить тесты.
# Install mocha globally npm install -g mocha # Run mocha tests mocha
Вы также можете запустить npm test
для выполнения тестов. Вы должны получить следующий вывод:
Все тесты не пройдены. Чтобы выяснить проблему, мы собираемся запустить тесты в режиме отладки. Для этого нам нужна новая конфигурация. Перейдите на панель отладки и щелкните раскрывающийся список, чтобы получить доступ к параметру « Add Configuration
:
launch.json
файл launch.json
с всплывающим списком нескольких конфигураций на выбор.
Просто выберите Mocha Tests . Следующая конфигурация будет вставлена для вас:
{ "type": "node", "request": "launch", "name": "Mocha Tests", "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", "args": [ "-u", "tdd", "--timeout", "999999", "--colors", "${workspaceFolder}/test" ], "internalConsoleOptions": "openOnSessionStart" },
Настройки по умолчанию в порядке. Вернитесь в выпадающий список и выберите Mocha Tests . Вам нужно будет закомментировать последние три строки, которые вы добавили в places.js
; в противном случае тесты не будут выполняться, как ожидалось. Вернитесь к placesTest.js
и добавьте placesTest.js
останова на линии непосредственно перед тем, где произойдет первый сбой теста. Это должна быть строка семь, где написано:
addPlace('Nairobi', 'Kenya');
Обязательно добавьте выражение places.length
в разделе часов. Нажмите кнопку Play , чтобы начать сеанс отладки.
В начале теста places.length
должно places.length
ноль. Если вы нажмете places.length
, places.length
2, но добавлено только одно место Как это может быть?
Перезапустите сеанс отладки, и на этот раз используйте Step into, чтобы перейти к функции addPlace
. Отладчик проведет вас по places.js
. Значение places.length
все еще равно нулю. Нажмите Step over, чтобы выполнить текущую строку.
Ага! Значение places.length
просто places.length
на 1, но мы ничего не добавили в массив. Проблема вызвана оператором ++
который изменяет длину массива. Чтобы это исправить, просто замените строку на:
const id = places.length + 1;
Таким образом, мы можем безопасно получить значение id
без изменения значения places.length
. Пока мы все еще находимся в режиме отладки, давайте попробуем исправить еще одну проблему, когда свойству numType
присваивается значение, even
когда id
равен 1. Проблема, по-видимому, заключается в выражении модуля внутри оператора if:
Давайте сделаем быстрый эксперимент, используя консоль отладки. Начните вводить правильное выражение для оператора if
:
Консоль отладки аналогична консоли браузера. Это позволяет вам проводить эксперименты с использованием переменных, которые в настоящее время находятся в области видимости. Испытав несколько идей в консоли, вы можете легко найти решение, даже не выходя из редактора. Давайте теперь исправим ошибочный оператор if:
if (id % 2 === 0) { numType = 'even'; }
Перезапустите сеанс отладки и нажмите « Продолжить», чтобы пропустить текущую точку останова. Первый тест «могу добавить место» сейчас проходит. Но второго теста нет. Чтобы это исправить, нам нужна еще одна точка останова. Удалите текущую и поместите новую точку останова в строку 16, где написано:
addPlace('Cape Town', 'South Africa');
Начать новый сеанс отладки:
Там! Посмотрите на раздел Переменные . Еще до того, как начинается второй тест, мы обнаруживаем, что в массиве places
уже есть данные, созданные в первом тесте. Это явно загрязнило наш текущий тест. Чтобы это исправить, нам нужно реализовать какую-то функцию setup
которая сбрасывает массив places
для каждого теста. Чтобы сделать это в Mocha, просто добавьте следующий код перед тестами:
beforeEach(() => { places.length = 0; });
Перезапустите отладчик и дайте ему остановиться на точке останова. Теперь массив places
имеет чистое состояние. Это должно позволить нашему тесту работать незагрязненным. Просто нажмите « Продолжить», чтобы выполнить остальную часть тестового кода.
Все тесты сейчас проходят. Вы должны чувствовать себя довольно здорово, так как вы научились отлаживать код без написания ни одной строки console.log
. Давайте теперь посмотрим, как отлаживать клиентский код с помощью браузера.
Отладка JavaScript с помощью Chrome Debugger
Теперь, когда вы ознакомились с основами отладки JavaScript в VS Code, мы увидим, как отладить немного более сложный проект с помощью расширения Debugger for Chrome . Просто откройте панель Marketplace через панель действий. Найдите расширение и установите его.
После установки нажмите перезагрузить, чтобы активировать расширение. Давайте быстро рассмотрим код, который будем отлаживать. Веб-приложение — это в основном клиентский JavaScript-проект, который запускается с помощью сервера Express:
const express = require('express'); const app = express(); const port = 3000; // Set public folder as root app.use(express.static('public')); // Provide access to node_modules folder app.use('/scripts', express.static(`${__dirname}/node_modules/`)); // Redirect all traffic to index.html app.use((req, res) => res.sendFile(`${__dirname}/public/index.html`)); app.listen(port, () => { console.info('listening on %d', port); });
Весь код на стороне клиента находится в public
папке. Зависимости проекта включают в себя Semantic-UI-CSS, jQuery, Vanilla Router, Axios и Handlebars. Вот как выглядит проект, когда вы запускаете его при npm start
. Вам нужно открыть URL localhost: 3000 в вашем браузере, чтобы просмотреть приложение.
Попробуйте добавить новое место. Когда вы это сделаете, вы увидите, что ничего не происходит. Очевидно, что-то идет не так, так что пришло время заглянуть под капот. Сначала мы рассмотрим код, прежде чем мы начнем сеанс отладки. Откройте public/index.html
. Наше внимание в настоящее время находится в этом разделе:
<!-- TEMPLATES --> <!-- Places Form Template --> <script id="places-form-template" type="text/x-handlebars-template"> <h1 class="ui header"> <i class="map marker alternate icon"></i> <div class="content"> Places</div> </h1> <hr> <br> <form class="ui form"> <div class="fields"> <div class="inline field"> <label>City</label> <input type="text" placeholder="Enter city" id="city" name="city"> </div> <div class="inline field"> <label>Country</label> <input type="text" placeholder="Enter Country" name="country"> </div> <div class="ui submit primary button">Add Place</div> </div> </form> <br> <div id="places-table"></div> </script> <!-- Places Table Template --> <script id="places-table-template" type="text/x-handlebars-template"> <table class="ui celled striped table"> <thead> <tr> <th>Id</th> <th>City</th> <th>Country</th> <th>NumType</th> </tr> </thead> <tbody> {{#each places}} <tr> <td>{{id}}</td> <td>{{city}}</td> <td>{{country}}</td> <td>{{numType}}</td> </tr> {{/each}} </tbody> </table> </script>
Если вы бросите быстрый взгляд, код будет правильным. Так что проблема должна быть в app.js
Откройте файл и проанализируйте код там. Ниже приведены разделы кода, на которые следует обратить внимание. Не торопитесь, чтобы прочитать комментарии, чтобы понять код.
// Load DOM roots const el = $('#app'); const placesTable = $('#places-table'); // Initialize empty places array const places = []; // Compile Templates const placesFormTemplate = Handlebars.compile($('#places-form-template').html()); const placesTableTemplate = Handlebars.compile($('#places-table-template').html()); const addPlace = (city, country) => { const id = places.length + 1; const numType = (id % 2 === 0) ? 'even' : 'odd'; places.push({ id, city, country, numType, }); }; // Populate places array addPlace('Nairobi', 'Kenya'); ... // Places View - '/' router.add('/', () => { // Display Places Form const html = placesFormTemplate(); el.html(html); // Form Validation Rules $('.ui.form').form({ fields: { city: 'empty', country: 'empty', }, }); // Display Places Table const tableHtml = placesTableTemplate({ places }); placesTable.html(tableHtml); $('.submit').on('click', () => { const city = $('#city').val(); const country = $('#country').val(); addPlace(city, country); placesTable.html(placesTableTemplate({ places })); $('form').form('clear'); return false; }); });
Все вроде нормально. Но в чем может быть проблема? Давайте разместим точку останова в строке 53, где написано:
placesTable.html(tableHtml);
Затем создайте конфигурацию Chrome через панель отладки. Выберите выделенный вариант:
Затем обновите конфигурацию Chrome следующим образом, чтобы она соответствовала нашей среде:
{ "type": "chrome", "request": "launch", "name": "Launch Chrome", "url": "http://localhost:3000", "webRoot": "${workspaceFolder}/public" },
Затем запустите сервер как обычно, используя npm start
или node server
. Затем выберите « Запустить Chrome» и запустите сеанс отладки. Новый экземпляр Chrome будет запущен в режиме отладки, и выполнение должно быть приостановлено, когда вы установите точку останова. Сейчас самое время расположить код Visual Studio и экземпляр Chrome рядом, чтобы вы могли эффективно работать.
Наведите курсор мыши на константу placesTable
. Появляется всплывающее окно, но оно кажется пустым. На панели часов добавьте выражения el
и placesTable
. Или, в качестве альтернативы, просто прокрутите вверх, где константы были объявлены.
Обратите внимание, что el
заполнен, но placesTable
пуст. Это означает, что jQuery не смог найти элемент #places-table
. Давайте вернемся к public/index.html
и выясним, где находится эта #places-table
.
Ага! Таблица div, которую мы хотим, находится в строке 55, прямо внутри places-form-template
. Это означает, что #places-table
div #places-table
может быть найдена только после загрузки шаблона places-form-template
. Чтобы это исправить, просто вернитесь в app.js
и переместите код в строку 52 сразу после комментария «Показать таблицу мест»:
const placesTable = $('#places-table');
Сохраните файл и перезапустите сеанс отладки. Когда он достигнет точки останова, просто нажмите « Продолжить» и дождитесь завершения выполнения кода. Теперь таблица должна быть видна:
Теперь вы можете удалить точку останова. Давайте попробуем добавить новое место — например, Кейптаун, Южная Африка
Хм … это не правильно. Место добавлено, но страна не отображается. Очевидно, что проблема не в коде таблицы HTML, поскольку в первой строке заполняется ячейка страны, поэтому что-то должно происходить на стороне JavaScript. Откройте app.js
и добавьте app.js
останова в строку 58, где написано:
addPlace(city, country);
Перезапустите сеанс отладки и попробуйте снова добавить новое место. Выполнение должно быть приостановлено в точке останова, которую вы только что установили. Начните зависать над соответствующими переменными. Вы также можете добавить выражения на панель часов, как показано ниже:
Как видите, переменная country
не определена, а переменная city
-. Если вы посмотрите на выражения селектора jQuery, которые были настроены на панели просмотра, вы заметите, что селектор #country
ничего не возвращает. Это означает, что его не было в DOM. Перейдите на index.html
чтобы проверить.
Увы! Если вы посмотрите на строку 59, в которой введены данные о стране, в ней отсутствует атрибут ID. Вы должны добавить один, как это:
<input type="text" placeholder="Enter Country" name="country" id="country">
Перезапустите сеанс отладки и попробуйте добавить новое место.
Теперь это работает! Отличная работа по исправлению еще одной ошибки без console.log
. Давайте теперь перейдем к нашей последней ошибке.
Отладка клиентской маршрутизации
Нажмите на ссылку Преобразовать на панели навигации. Вы должны перейти к этому представлению, чтобы выполнить быстрое преобразование:
Это работает нормально. Там нет ошибок.
На самом деле есть, и они не имеют ничего общего с формой. Чтобы найти их, обновите страницу.
Как только вы нажмете перезагрузить, пользователь перейдет обратно в /
, корень приложения. Это явно проблема маршрутизации, которую должен решать пакет Vanilla Router. Вернитесь в app.js
и найдите эту строку:
router.navigateTo(window.location.path);
Предполагается, что этот фрагмент кода направляет пользователей на правильную страницу на основе предоставленного URL-адреса. Но почему это не работает? Давайте добавим точку останова здесь, затем вернемся к URL-адресу /convert
и попробуйте обновить страницу еще раз.
Как только вы обновите, редактор останавливается на точке останова. Наведите курсор на экспресс windows.location.path
. Появляется всплывающее окно, которое говорит, что значение не undefined
. Давайте перейдем к консоли отладки и начнем набирать выражение ниже:
Задерживать! Консоль отладки просто дала нам правильное выражение. Предполагается прочитать window.location.pathname
. Исправьте строку кода, удалите точку останова и перезапустите сеанс отладки.
Перейдите к URL-адресу /convert
и обновите его. Страница должна перезагрузить правильный путь. Потрясающие!
Это последняя ошибка, которую мы собираемся устранить, но я рекомендую вам продолжать экспериментировать в сеансе отладки. Установите новые контрольные точки для проверки других переменных. Например, проверьте объект response
в функции router('/convert')
. Это демонстрирует, как вы можете использовать сеанс отладки, чтобы выяснить структуру данных, возвращаемых запросом API при работе с новыми конечными точками REST.
Резюме
Теперь, когда мы подошли к концу этого урока, вы должны гордиться собой за то, что вы приобрели жизненно важный навык в программировании. Изучение правильной отладки кода поможет вам быстрее исправить ошибки. Тем не менее, вы должны знать, что в этой статье только поверхностно рассматривается то, что возможно, и вам следует ознакомиться с полной документацией по отладке VS Code. Здесь вы найдете более подробную информацию о конкретных командах, а также о типах точек останова, которые мы не рассмотрели, таких как условные точки останова .
Я надеюсь, что теперь вы перестанете использовать console.log
для отладки и вместо этого доберетесь до VS Code, чтобы начать отладку JavaScript как профессионал!