Как освоить отладку JavaScript
По мере того как ваше веб-приложение становится все сложнее, становится необходимым овладеть искусством отладки.
Эффективная отладка JavaScript включает в себя нечто большее, чем просто исправление ошибок. Для обеспечения бесперебойной работы приложения и наилучшего взаимодействия с пользователем требуется понимание того, как работает ваш код.
Сокращенный код, который представляет собой версию вашего кода, доступную пользователям в рабочей среде, оптимизирован для повышения производительности. Однако отладка сокращенного кода может стать настоящим кошмаром. Когда пользователи сталкиваются с ошибками, воспроизведение и диагностика проблем в сокращенном коде часто является сложной задачей.
Однако при наличии правильных инструментов отладка JavaScript может стать намного проще. В этой статье мы рассмотрим, как использовать сопоставления исходных текстов для отладки сокращенного кода, а также другие методы с помощью Chrome DevTools для эффективного выявления и устранения проблем в вашем веб-приложении.
Пример приложения
Мы будем работать над простым приложением, которое увеличивает количество вычислений и регистрирует их в консоли. Это приложение демонстрирует, как сокращенный код может усложнить отладку и как карты исходных текстов могут помочь упростить процесс.
Создайте js-файлы, указанные ниже, и добавьте фрагменты кода, как показано на рисунке:
1.... src/counterCache.js
export const countCache = {
previousCount: 0,
currentCount: 0,
totalCount: 0
}
export function updateCache(currentCount, previousCount) {
countCache.currentCount = currentCount;
countCache.previousCount = previousCount; c
ountCache.totalCount = countCache.totalCount + countCache.currentCount;
}
2.src/counter.js:
import { updateCache } from './counterCache.js';
let count = 0;
export function incrementCounter()
{ count += 1;
const previousCount = count;
updateCache(count, previousCount);
}
3.src/index.js:
import { incrementCounter } from './counter';
import { countCache } from './counterCache';
const button = document.createElement('button');
const previousElement = document.getElementById('previous');
const currentElement = document.getElementById('current');
const totalElement = document.getElementById('total');
button.innerText = 'Click me';
document.body.appendChild(button);
button.addEventListener('click', () => {
incrementCounter();
previousElement.innerText = countCache.previousCount;
currentElement.innerText = countCache.currentCount;
totalElement.innerText = countCache.total();
});
В свой файл package.json добавьте пакеты webpack, как показано ниже, затем запустите npm i для их установки. Мы будем использовать webpack как часть процесса сборки для создания сокращенного кода для производства:
"devDependencies": {
"webpack": "^5.96.1",
"webpack-cli": "^5.1.4"
}
Чтобы включить минимизацию кода, добавьте файл webpack.config.js со следующим фрагментом. Установка режима на рабочий указывает webpack на необходимость применения оптимизаций, таких как модификация:
const path = require('path');
module.exports = {
mode: 'production', // Enables optimizations like minification and tree-shaking
entry: './src/index.js', // Specifies the entry point of your application
output: {
path: path.resolve(__dirname, 'dist'),// Defines the output directory for bundled files
filename: 'bundle.js',// Specifies the name of the bundled file
},
};
Теперь запустите npx webpack, чтобы объединить и минимизировать ваш код. dist/bundle.js Файл создается с содержимым, как показано ниже. При минимизации скрываются имена переменных и функций и удаляются ненужные символы, такие как пробелы, комментарии и неиспользуемый код, что позволяет уменьшить размер выходного файла и ускорить его загрузку:
(()=>{"use strict";const t={};let e=0;const n=document.createElement("button"),o=document.getElementById("previous"),u=document.getElementById("current"),r=document.getElementById("total");n.innerText="Click me",document.body.appendChild(n),n.addEventListener("click",(()=>{var n,c;e+=1,n=e,c=e,t.currentCount=n,t.previousCount=c,t.totalCount=t.totalCount||0+t.currentCount,o.innerText=t.previousCount,u.innerText=t.currentCount,r.innerText=t.total()}))})();
Затем обновите файл index.html, чтобы он ссылался на выходные данные пакета, и убедитесь, что ваше приложение использует сокращенный код:
<<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Debugging Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Web Debug App</h1>
<p>Check console for bug</p>
<table>
<thead>
<tr>
<th>Previous count</th>
<th>Current count</th>
<th>Total count</th>
</tr>
</thead>
<tbody>
<tr>
<td id="previous">0</td>
<td id="current">0</td>
<td id="total">0</td>
</tr>
</table>
<script src="./dist/bundle.js" ></script> <!-- Include the bundled output -->
</body>
</html>
Наконец, запустите приложение и проверьте консоль после нажатия кнопки. Для локального просмотра приложения вы можете использовать расширение Live Server в VS Code:
Ошибку в консоли, t.total не является функцией, трудно интерпретировать. Щелчок по файлу в консоли не помогает точно определить проблему из-за компактности и запутанности сокращенного кода. Выявление первопричины такой ошибки в большой кодовой базе может быть неприятным и отнимать много времени, поскольку сокращенный код скрывает исходную логику и контекст.
8 Стратегий отладки JavaScript для веб-приложений
Давайте продемонстрируем восемь методов, которые помогут немного упростить отладку JavaScript:
1. Исходные карты
Исходные карты - это файлы, которые преобразуют ваш уменьшенный код в исходный. Они упрощают отладку и помогают выявлять проблемы в рабочей среде. Имена файлов исходных карт заканчиваются на .map.
Чтобы сгенерировать исходные карты с помощью webpack, обновите файл webpack.config.js следующим образом:
Строка devtool: 'source-map' или devtool: 'eval-source-map' указывает webpack сгенерировать внешний файл .map, который сопоставляет уменьшенный код с вашим исходным кодом. URL-адрес исходного файла карты также добавляется к уменьшенному коду в файле bundle.js.
Теперь запустите npx webpack. Файл .map будет создан вместе с вашим уменьшенным пакетом. Запустите приложение с помощью локального сервера и откройте его в окне браузера в режиме инкогнито. Это предотвратит вмешательство расширений браузера и кэшированных файлов в процесс отладки.
При создании исходных карт делаются следующие наблюдения:
- Ошибка связана с файлом counter.js, который является исходным кодом
- Исходная карта, bundle.js.map, успешно извлечена и видна на вкладке Ресурсы разработчика
- На вкладке "Источники" инструменты разработчика отображают исходный код и проблемную строку
Точный код и файл, вызывающие ошибку, легко идентифицировать с помощью исходных карт:
С описанной выше явной ошибкой мы можем исправить ошибку и получить доступ к правильному свойству в countCache.
Наше руководство по использованию Chrome DevTools должно стать отличным началом работы. Чтобы открыть вкладку "Ресурсы разработчика", нажмите на значок "Еще", затем "Дополнительные инструменты" и "Ресурсы разработчика". На этой вкладке вы можете просмотреть статус загрузки исходных карт и даже загрузить исходные карты вручную:
Приведенный ниже фрагмент кода исправляет ошибку в консоли. Обновите свой код, затем запустите npx webpack для компиляции изменений. После завершения запустите приложение и просмотрите обновленные выходные данные в таблице:
totalElement.innerText = countCache.totalCount;
При нажатии на кнопку в настоящее время обновляется предыдущее значение count, текущее значение count и итоговое значение в таблице. Предполагается, что предыдущее значение count возвращает предыдущее значение count, а общее значение count возвращает сумму всех значений count. На данный момент предыдущее количество отображает текущее количество, в то время как общее количество остается равным единице.
В следующем разделе мы рассмотрим дополнительные методы отладки JavaScript, такие как использование точек останова и пошаговое выполнение кода, чтобы выявить и устранить эту проблему:
2. Точки останова
Точки останова позволяют приостанавливать выполнение кода на определенных строках, что помогает проверять переменные, вычислять выражения и понимать последовательность выполнения кода. В зависимости от вашей цели вы можете использовать различные точки останова. Например:
- Строка кода... Приостанавливает выполнение вашего кода точно на указанной строке
- Условная строка кода Приостанавливает выполнение только при выполнении указанного условия
- Logpoint не приостанавливает выполнение кода, а вместо этого отправляет пользовательское сообщение на консоль при выполнении этой строки кода
В нашем примере приложения мы применим точку останова к функции incrementCounter. На панели "Источники" откройте файл counter.js и щелкните слева от шестой строки. Это устанавливает точку останова в строке кода после увеличения количества:
Мы установим другую точку останова в пятой строке и отредактируем ее. Чтобы отредактировать нашу точку останова, мы щелкнем правой кнопкой мыши на выделенном разделе и затем выберем "Редактировать точку останова".:
Мы установим тип точки останова на Logpoint, затем введем сообщение, которое будет записано в консоль:
При нажатии на кнопку наше приложение приостанавливает работу в точке останова строки кода и выводит журнал отладки на консоль из заданной точки входа:
На изображении мы можем видеть следующие разделы:
- Панель Точки останова" Помогает управлять вашими точками останова и переключать их. В настоящее время мы добавили две точки останова, в пятой и шестой строках. Эти точки останова можно включить или отключить с помощью панели
- Панель Область действия" имеет решающее значение для проверки состояний и значений переменных в текущей точке останова
- Элементы управления отладкой Это позволяет вам шаг за шагом перемещаться по вашему коду. Используются следующие элементы управления: возобновить, перейти, войти, выйти и step
Благодаря этому мы сможем продолжить отладку нашего приложения.
3. Панель управления
Панель scope может быть эффективна для отладки JavaScript, поскольку она позволяет просматривать переменные из исходного кода:
Мы можем видеть следующие переменные области видимости:
- Локальные Это переменные, определенные в текущей выполняемой функции
- Закрытие Эти переменные извлекаются из областей внешнего блока выполняющейся функции или скрипта
- Закрытие Этот тип переменной получается из сгенерированных областей, например, с использованием файлов модуля
- Глобальные Это переменные, доступные во всем приложении
На панели scope и в точке останова log point мы можем видеть, что текущее значение равно единице, в то время как значение до увеличения равно нулю. Поэтому нам нужно сохранить значение до увеличения как предыдущее значение.
4. Пошаговое выполнение кода (step into, step over, step out)
Пошаговое выполнение вашего кода включает в себя навигацию по программе различными способами во время отладки JavaScript:
- Переход в ... Позволяет вам выполнить вызов функции и изучить код внутри этой функции
- Перешагнуть - Пропускает вызов функции, выполняя его без погружения в
- Выйдите из функции - Позволяет вернуться к контексту вызывающей функции, если вы вошли в него
Вы можете использовать элементы управления отладкой для пошагового выполнения вашего кода. Элемент управления Step позволяет запускать ваш код по одной строке за раз. При нажатии на Step выполняется шестая строка и выполняется переход к седьмой строке. Обратите внимание, как изменяется значение previousCount в области видимости:
Пошаговое управление позволяет вам выполнять функцию, не проходя ее построчно:
Переход к элементу управления позволяет вам перейти к функции. В функции вы можете пошагово просматривать код построчно или выйти из функции, как показано ниже. Выход из функции завершит выполнение оставшихся строк:
Â'Â
Чтобы устранить проблему, мы обновим код, как показано ниже. Теперь в таблице корректно отображается предыдущее значение:
import { updateCache } from './counterCache.js';
let count = 0;
export function incrementCounter() {
const previousCount = count;
count += 1;
updateCache(count, previousCount);
}
5. Стек вызовов
Стек вызовов показывает последовательность вызовов функций, которые привели к текущей точке кода.
Добавьте новую точку останова в файл counterCache.js как показано на рисунке, затем нажмите кнопку. Обратите внимание на панель стека вызовов:
Когда приложение выполняет шестую строку из counterCache.js. Чтобы наблюдать за выполнением любых функций в стеке, вы можете перезапустить их выполнение, используя Restart frame, как показано ниже.:
6. Игнорирование скриптов
При отладке вы можете захотеть игнорировать определенные скрипты в ходе рабочего процесса. Это помогает избежать сложностей кода из библиотек или генераторов кода. В нашем случае мы хотим игнорировать скрипт counter.js во время отладки.
На вкладке Страница щелкните правой кнопкой мыши на файле, который нужно игнорировать, и добавьте скрипт в список игнорируемых:
Запустив приложение и сделав паузу в точке останова, мы видим, что функция incrementCounter теперь игнорируется в стеке вызовов. Вы можете скрыть или отобразить игнорируемые фреймы:
Вы можете сгруппировать свои файлы на вкладке Страницы для удобства навигации, как показано на рисунке ниже:
7. Следите за выражением лица
Отслеживание выражений позволяет отслеживать определенные переменные или выражения во время выполнения кода, что помогает отслеживать изменения в режиме реального времени. Вы можете добавить выражения, такие как countCache, для отслеживания значений по мере выполнения кода.:
8. Фрагменты кода для отладки
Чтобы попытаться исправить ошибку с общим подсчетом, вы можете запустить фрагменты кода на консоли, чтобы понять логическую ошибку. При отладке кода, который вы неоднократно запускаете на консоли, вы можете использовать фрагменты кода.
На вкладке Фрагменты добавьте пример сценария отладки, сохраните сценарий и нажмите Enter, чтобы запустить сценарий:
Вы можете заметить, что выражение с ошибкой необходимо изменить, чтобы устранить проблему:
countCache.totalCount = (countCache.totalCount || 0) + currentCount;
Вы можете ознакомиться с дополнительными ресурсами по отладке веб-приложений, такими как эта статья об отладке приложений React с помощью React DevTools, в которой содержится ценная информация об отладке приложений на основе React. Кроме того, в этом руководстве по отладке Node.js с помощью Chrome DevTools приведены советы по отладке серверного JavaScript с использованием средств просмотра и других расширенных функций DevTools. Эти ресурсы могут дополнить описанные здесь методы и расширить ваши представления об отладке веб-приложений.
Вывод
В этом руководстве рассматривается отладка сокращенного кода с использованием карт исходного кода и Chrome DevTools. Создав карты исходного кода, мы вернули уменьшенный код к его исходному коду, что упростило отладку нашего веб-приложения. Chrome DevTools еще больше улучшил процесс отладки JavaScript с помощью таких методов, как точки останова, пошаговое выполнение кода, контрольные выражения и многое другое.
С помощью этих инструментов разработчики могут эффективно отлаживать и оптимизировать свои приложения, даже когда имеют дело со сложными, сокращенными кодовыми базами. Полный код для этого проекта можно найти на GitHub.