Статьи

Отладка проектов JavaScript с помощью VS Code & Chrome Debugger

Отладка 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 :

  1. в массиве несколько пробелов, то есть places[0] и places[2] не undefined
  2. свойство 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'); 

Начать новый сеанс отладки:

Мокко test2 провал

Там! Посмотрите на раздел Переменные . Еще до того, как начинается второй тест, мы обнаруживаем, что в массиве places уже есть данные, созданные в первом тесте. Это явно загрязнило наш текущий тест. Чтобы это исправить, нам нужно реализовать какую-то функцию setup которая сбрасывает массив places для каждого теста. Чтобы сделать это в Mocha, просто добавьте следующий код перед тестами:

 beforeEach(() => { places.length = 0; }); 

Перезапустите отладчик и дайте ему остановиться на точке останова. Теперь массив places имеет чистое состояние. Это должно позволить нашему тесту работать незагрязненным. Просто нажмите « Продолжить», чтобы выполнить остальную часть тестового кода.

Мокко тесты пройдены

Все тесты сейчас проходят. Вы должны чувствовать себя довольно здорово, так как вы научились отлаживать код без написания ни одной строки console.log . Давайте теперь посмотрим, как отлаживать клиентский код с помощью браузера.

Отладка JavaScript с помощью Chrome Debugger

Теперь, когда вы ознакомились с основами отладки JavaScript в VS Code, мы увидим, как отладить немного более сложный проект с помощью расширения Debugger for Chrome . Просто откройте панель Marketplace через панель действий. Найдите расширение и установите его.

Отладчик для Chrome

После установки нажмите перезагрузить, чтобы активировать расширение. Давайте быстро рассмотрим код, который будем отлаживать. Веб-приложение — это в основном клиентский 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

Затем обновите конфигурацию Chrome следующим образом, чтобы она соответствовала нашей среде:

 { "type": "chrome", "request": "launch", "name": "Launch Chrome", "url": "http://localhost:3000", "webRoot": "${workspaceFolder}/public" }, 

Затем запустите сервер как обычно, используя npm start или node server . Затем выберите « Запустить Chrome» и запустите сеанс отладки. Новый экземпляр Chrome будет запущен в режиме отладки, и выполнение должно быть приостановлено, когда вы установите точку останова. Сейчас самое время расположить код Visual Studio и экземпляр Chrome рядом, чтобы вы могли эффективно работать.

Отладка JavaScript с помощью Chrome и VS Code

Наведите курсор мыши на константу 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 как профессионал!