Статьи

Современный опыт отладки: часть 2

В первой части мы увидели, как писать и выполнять JavaScript с помощью DevTools. Во второй части мы рассмотрим отладку JavaScript и принятие рабочего процесса таким образом, чтобы решение ошибок JavaScript и диагностика проблем стали более эффективными.

Вы можете использовать ключевое слово debugger непосредственно в своем коде, чтобы вызвать возможности отладки (если таковые имеются) среды выполнения JavaScript. Эффект добавления debugger ключевых слов в ваш код идентичен ручному заданию точки останова через пользовательский интерфейс DevTools. В Chrome ключевое слово debugger не действует, пока DevTools закрыт.

Средства управления отладчиком обеспечивают точный контроль над потоком отладки. Используйте их при остановке на точке останова, чтобы эффективно перемещаться по коду JavaScript. Каждому элементу управления отладчиком, перечисленному в этом разделе, соответствует кнопка в инструментах DevTools, которую вы можете выбрать во время паузы в точке останова.

Оставляет текущую точку останова и возобновляет выполнение кода как обычно. Это не влияет на другие точки останова, которые еще не были приостановлены.

Используйте Continue когда текущая приостановленная точка останова не помогает, и вы хотите, чтобы выполнение кода возобновилось как обычно.

Пошагово проходите код (одна строка за клик), пока не будет достигнут вызов функции. На этом этапе вызов функции переходит «поверх», и вы не вступаете в этот конкретный вызов функции.

Используйте Step Over когда то, что вы пытаетесь решить, ограничено текущей функцией, и вам не нужно смотреть на внешние вызовы функций.

Аналогично Step Over , за исключением того, что в этом случае вы переходите к вызовам внешних функций, переходя к их первой строке.

Используйте Step Into когда вас интересует построчное выполнение, а также любые внешние вызовы функций.

Когда вы входите в функцию, Step Out будет продолжать выполнять код остальных функций, однако он не отлажен.

Используйте Step Out если вас не интересует оставшаяся часть текущей функции и вы хотите продолжить отладку за ее пределами.

Стек вызовов активен, когда приостановлен в точке останова. Путь выполнения, который ведет к приостановленной в данный момент точке останова, отображается в стеке вызовов, причем верхний вызов является самым последним.

Каждый вызов в стеке содержит:

  • имя функции
  • имя файла, содержащего функцию
  • строка кода, в которой существует функция

Нажмите на любой вызов в стеке, чтобы перейти к его точке в исходном коде с выделенной соответствующей строкой. Чтобы скопировать трассировку стека в буфер обмена, щелкните правой кнопкой мыши вызов и выберите « Копировать трассировку стека» . В контекстном меню стека вызовов также можно выбрать « Перезапустить кадр» .

Рассмотрим вариант использования, в котором отладчик остановился на полпути через функцию обратного вызова, запускаемую обработчиком события click, и вы пытаетесь отладить, почему поиск target не работает должным образом.

Вы видите, что была сделана попытка доступа к целевому свойству как части ключевого слова this , но затем вы вспоминаете, что это часть свойства объекта события, переданного в качестве аргумента функции обратного вызова.

Вы можете переписать функцию, используя Live Edit, чтобы убедиться, что ваши изменения работают, и новый JavaScript внедряется в движок V8.

Когда вы пишете обработчик события для события, такого как прокрутка, вы можете начать с использования console.log чтобы увидеть, как выглядит переданный аргумент (объект события). Быстрый совет для этого — использовать ярлык monitorEvents . Вставьте следующий код в консольную панель и затем прокрутите страницу:

1
monitorEvents(window, «resize»);

Обратите внимание, что объект события зарегистрирован на консоли и готов к проверке.

Если вы хотите, чтобы отладчик сделал паузу в первой строке функции во время ее выполнения, вы можете выполнить одно из следующих действий:

  • Добавьте точку останова через пользовательский интерфейс DevTools.
  • Добавьте оператор отладчика в функцию.

Другой метод — выполнить debug(fn) которая является частью API командной строки. Функция принимает функцию, которую вы хотите отладить, в качестве аргумента и разбивает первую строку выполнения этой функции.

Этот метод позволяет вам приостановить отладчик, когда свойство интересующего вас объекта доступно любым способом (чтение или запись). Чтобы прервать чтение или запись свойства объекта, выполните следующее (через панель консоли или фрагменты ):

1
2
3
4
5
6
7
8
Object.defineProperty(document.body, ‘scrollTop’, {
    get: function () {
        debugger;
    },
    set: function (val) {
        debugger;
    }
});

Это применяет метод получения и scrollTop свойству scrollTop объекта document.body . В пользовательских методах get и set существует оператор отладчика. Вы также можете использовать Object.observe для разбиения на дополнения свойств для указанного объекта:

1
2
3
4
var watchMe = {};
Object.observe(watchMe, function() {
  debugger;
});

Помимо ключевого слова отладчика, чтобы установить точку останова с помощью DevTools, вы можете щелкнуть строку кода, по которой вы хотите разбить строку-желоб. Этот метод установки точки останова имеет дополнительную функциональность: вы устанавливаете условную точку останова, которая будет инструктировать DevTools делать паузу в точке останова, только если определенное выражение оценивается как true. Например, вы можете установить условную точку останова на паузу, только если существует аргумент ошибки.

Чтобы установить условную точку останова:

  1. Щелкните правой кнопкой мыши внутри линии желоба.
  2. Выберите Добавить условную точку останова .
  3. Введите выражение, которое вы хотите, чтобы DevTools оценил.
  4. Нажмите Enter .
Добавить условную точку останова

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

Когда отладчик приостановлен в точке останова, вы можете вызвать консольную панель в режиме ящика, используя клавишу Escape . Код, который вы вводите, оценивается в том же контексте, что и точка, в которой вы находитесь в режиме паузы, а это означает, что переменные, которые находятся в области видимости, будут вам доступны.

Смотреть выражения

Выражение Watch — это инструмент, упрощающий технику регулярной проверки (например, через console.log ) переменных области действия. Watch Expressions — это панель в панели источников. Вы можете добавлять или удалять Watch Expressions, используя кнопки « Плюс» и « Минус» . Типичный объект для наблюдения — this объект this ; обратите внимание, как он обращается к глобальному объекту окна, когда вы не остановлены на точке останова.

Watch Expressions, как правило, обновляются во время выполнения кода. Если этого не произойдет, нажмите кнопку « Обновить» .

Рассмотрим следующий скрипт:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
function a() {
    return b();
}
 
function b() {
    return c();
}
 
function c() {
    console.trace(‘The Trace’);
    return 42;
}
 
a();
Исключения

Есть три объявленные функции. Функция a вызывает функцию b , затем функция b вызывает функцию c . Скрипт инициирует цепочку с вызовом функции a . Оператор console.trace записывает на консоль трассировку стека от точки, где был вызван метод. Использование console.trace отображает результат использования console.trace .

Обратите внимание, что имена функций и строки, где они вызываются, отображаются в сообщении трассировки. Вы можете щелкнуть номер строки, чтобы перейти к ее точке в исходном коде через панель источников. Эта техника также работает для фрагментов кода.

Отладчик предлагает различные режимы для работы с исключениями:

  • Пауза на неисследованных исключениях.
  • Пауза на пойманных и неучтенных исключениях.
  • Не останавливайтесь на исключениях.

Когда вам нужно отладить сайт, о котором вы мало что знаете, вы можете использовать другую технику отладки. При таком подходе вы подключаетесь к событиям, которые, по вашему мнению, сработают, и запрашивают разрывы DevTools для таких событий, если и когда они происходят. Существует две категории точек входа «снаружи> в»:

  • Модификации DOM
  • Точки останова прослушивателя событий

У вас есть задача отладки веб-страницы, в частности DOM. Узлы добавляются и удаляются в течение жизненного цикла страницы, и вам нужно проверить JavaScript, который делает это возможным. Установите точку останова DOM, выполнив следующие действия:

  • Щелкните правой кнопкой мыши узел DOM на панели элементов.
  • Выберите предпочтительную точку останова DOM из контекстного меню Break on .
  • Пока вы приостановлены в точке останова, вы можете увидеть сообщение, которое объясняет причину приостановки отладчиком, как показано в разделе Причина приостановки в точке останова.
Модификации DOM

Каждый раз, когда вы устанавливаете точку останова DOM, вы можете легко включать и выключать ее на панели точек останова DOM на панели элементов . На этой панели перечислены все установленные вами точки останова, и вы можете взаимодействовать с этой панелью следующими способами:

  • Установите или снимите флажок, чтобы включить или отключить точку останова.
  • Нажмите на имя узла (которое подчеркнуто), чтобы перейти к нему в виде дерева DOM.
  • Щелкните правой кнопкой мыши и выберите « Удалить все точки останова DOM», чтобы отключить и удалить все точки останова DOM.
DOM точки останова

Описание: модификация поддерева происходит при изменении дерева корневого узла (для которого установлена ​​точка останова). Это может включать добавление или удаление узлов.

Вариант использования: пустой контейнер div присутствует в DOM, и при загрузке страницы происходит запрос Ajax, который добавляет несколько новых узлов в исходный контейнер. Добавьте точку прерывания модификации поддерева в контейнер, чтобы увидеть точную точку в коде, которая добавляет новые узлы в DOM.

Примеры сообщений: Приостановлено на Subtree Modified точка останова, установленная в body , поскольку его потомок p был удален. Или: Приостановлено на Subtree Modified точка останова, установленная на div#parent , потому что новый узел был добавлен к этому узлу.

Описание: модификация атрибута срабатывает, когда имя или значение атрибута на узле добавляется, удаляется или изменяется. Это включает в себя все атрибуты, такие как class , data-* или style .

Случай использования: визуальное изменение происходит на странице в кажущийся случайный момент времени, и вы сужаете это до класса, который динамически устанавливается на элементе body. Вы хотите исследовать причину этого динамического добавления класса.

Пример сообщения: приостановлено для Attribute Modified установленного для точки останова p .

Описание: точка останова удаления узла срабатывает в точке, где узел удаляется из родительского объекта, содержащего установленную точку останова.

Вариант использования: вы создаете приложение списка дел и хотите убедиться, что когда пользователь удаляет элемент списка дел, он также удаляется из DOM. Вы можете установить точку останова удаления узла, чтобы гарантировать, что это происходит.

Пример сообщения: Приостановлено на Node Removed div#container .

В DevTools для включения доступно несколько предопределенных точек останова прослушивателя событий. Они предлагают точки входа в JavaScript, который принадлежит странице.

Рассмотрим простую about:blank страница. Установите точку останова прослушивателя событий click на этой странице, выполнив следующие действия:

  • Перейдите к панели « Точки останова приемника событий» на панели « Источники» .
  • Откройте категорию « Mouse событий Mouse ».
  • Включите прослушиватель событий Click .

Теперь вы установили точку останова. Если вы нажмете на страницу, обратите внимание, что ничего не происходит. Теперь выполните следующий фрагмент кода JavaScript на панели консоли .

1
document.addEventListener(‘click’, console.log.bind(console))

Когда вы устанавливаете точку останова для того же события, для которого вы зарегистрировали прослушиватель событий, отладчик делает паузу перед точкой, где выполняется обратный вызов вашего прослушивателя событий.

Вы можете зарегистрировать точки останова для многих типов событий, таких как таймеры, сенсорные события и другие, которые перечислены в таблице ниже.

Категория события Примеры событий

Анимация

requestAnimationFrame, cancelAnimationFrame, animationFrameFired

контроль

изменить размер, прокрутить, увеличить, фокус, размытие, выбрать, изменить, отправить, сбросить

буфер обмена

копировать, вырезать, вставлять, перед копированием, перед вырезкой, перед пастой

ДОМ Мутация

DOMActivate, DOMFocusIn, DOMFocusOut, DOMAttrModified, DOMCharacterDataModified, DOMNodeInserted, DOMNodeInsertedIntoDocument, DOMNodeRemoved, DOMNodeRemovedFromDocument, DOMSubtreeModified, DOMSubtreeModified,

устройство

Deviceorientation, Devicemotion

Перетаскивания

драгентер, драговер, драглайв, капля

клавиатура

keydown, keyup, нажатие клавиши, ввод

нагрузка

загрузить, до загрузки, выгрузить, прервать, ошибка, хэш-обмен, popstate

мышь

щелкните, dblclick, mousedown, mouseup, mouseover, mousemove, mouseout, колесико мыши, колесо

таймер

setTimer, clearTimer, timerFired

сенсорный

TouchStart, TouchMove, Touchend, TouchCancel

WebGL

webglErrorFired, webglWarningFired

Техника «отладки извне» может быть полезна, когда вам нужно отладить сторонний веб-сайт, функциональность которого нарушена, или даже когда вам интересно узнать, как что-то на странице, которую вы просматриваете, работает.

Существует ряд расширений Chrome, многие из которых расширяют функциональность DevTools. Список избранных находится в галерее расширений DevTools .

Для авторов расширений DevTools полезна тема предварительной обработки JavaScript . Препроцессор может перехватывать исходный код JavaScript до того, как он войдет в движок V8, что означает, что исходный код JavaScript может быть изменен с помощью DevTools, прежде чем он войдет в ВМ, все из расширения.

В дополнение к возможностям перехвата API предварительной обработки имеет программный доступ для повторной загрузки источников сценариев. Расширение может в любой момент в течение своего жизненного цикла перезагрузить исходный код JavaScript без перезагрузки исходной веб-страницы.

В этом разделе рассматриваются несколько инструментов, которые предлагают некоторый уровень интеграции между Node.js и Chrome DevTools.

В DevTools есть две части:

  • Front-end : это то, что вы используете и взаимодействуете. Он состоит из HTML, CSS и JavaScript.
  • Серверная часть . В случае проверки страницы в Google Chrome серверная часть находится внутри Chrome. Сообщения передаются взад и вперед по протоколу удаленной отладки .

Любое приложение может реализовать связь по протоколу удаленной отладки и позволить своим пользователям отлаживать через DevTools. Node Inspector — один из таких инструментов. После установки вы можете запустить любой скрипт узла с помощью Node Inspector. Инструмент запускает веб-сервер, на котором размещается интерфейс DevTools. Эта специальная версия DevTools использует не Chrome, а собственный Node Inspector.

Инспектор узлов

Как вы можете видеть в Node Inspector, DevTools приостановлен в точке останова. Стек вызовов относится к вызовам, выполненным в Node.js. Здесь задействовано только браузер для пользовательского интерфейса DevTools.

Используйте Node Heapdump, чтобы сделать снимок кучи V8 в определенный момент времени в вашем коде. Текущее состояние кучи V8 сериализуется и выводится в файл.

Узел Heapdump

Сравните два снимка кучи, чтобы узнать, какие объекты не являются сборщиком мусора. Это полезно для обнаружения утечек памяти.

Вот и все для этой серии из двух частей о современном опыте отладки. Надеемся, что в этот момент вам будет удобно создавать и отлаживать JavaScript в Chrome DevTools. Вы знакомы с рабочими процессами, которые могут помочь в отладке, и знаете некоторые советы и рекомендации при работе с рабочим сайтом, над которым вы раньше не работали. Обязательно попробуйте некоторые методы, которые вы изучили здесь, в следующий раз, когда вам нужно будет отладить.

Спасибо за чтение!