Продвинутая отладка Vue.js: Детективная история

Продвинутая отладка Vue.js: Детективная история

От автора: современные фреймворки, такие как Vue.js, делают за вас кучу всего. Они управляют обновлениями DOM, поддерживают жизненные циклы компонентов и многое другое.

Слой платформ более высокого уровня, таких как Nuxt.js, делает даже еще больше. Система плагинов позволяет автоматически смешивать поведение всех компонентов. Макеты, страницы и компоненты полностью переплетаются под капотом. Но один из ключевых вопросов — что происходит, когда что-то ломается? Когда что-то идет не так — а это случается весьма часто — как делается во Vue js отладка кода?

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

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

Настройка

Ошибка произошла в клиентском приложении, где я использовал компонент vue-select. Я обновил версию пакета vue-select с v2.4.0 до v2.5.0, чтобы получить новую функцию, но после тестирования обнаружил, что пакет больше не работает корректно.

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

Мое первое предположение заключалось в том, что что-то в том, как я использовал компонент, больше не поддерживалось. Я просмотрел документацию, и было похоже, что все, что я делал, делалось правильно … на самом деле там даже был пример, почти идентичный тому, как я использовал пакет.

Я скачал пакет с репозитория и включил в него мой пример — там все работало отлично. Так стало понятно, что происходит что-то странное. Настало время вникать в отладку.

Отправная точка — консоль

Мое первое действие — открыть консоль браузера и посмотреть, имела ли место ошибка JavaScript. Возможно, что-то еще в моем приложении давало сбой, и компонент не полностью настраивался. Хотя я не нашел ошибку, я увидел пару предупреждений:

‘Method «filterBy» has already been defined as a prop’ — это было похоже на подсказку. Может быть, я определял filterBy где-то, я не должен был этого делать? Но поиск по коду ничего не дал.

При просмотре исходного кода vue-select это больше нигде не высвечивалось. Я видел, что filterBy определяется как prop, но не переопределяется нигде, что могло привести к этому предупреждению. Если бы это была реальная ошибка, я мог бы отследить ее, но предупреждения поступают из глубин Vue.

Проверка компонента

Чтобы выяснить, что происходит, я использовал Vue devtools, я хотел проинспектировать компонент во время выполнения. Я знал, что по умолчанию свойство filterBy для vue-select должно быть установлено для функции, которая выглядит так:

function(option, label, search) { return (label || '').toLowerCase().indexOf(search.toLowerCase()) > -1
}

Я выбрал в Vue devtools компонент и использовал тот факт, что он создал ссылку на компонент с именем $vm0 для выхода из функции:

Совсем не то! На самом деле появилась новая функция… но когда я произвел поиск в своей базе кода по фильтру сигнатуры функции By(arr, search) или даже просто аргументов, ничего не нашлось.

И у меня все еще не было никаких мыслей относительно того, что и когда устанавливала эту новую функцию… только то, что что-то на самом деле устанавливало новую функцию.

Если бы я был тогда немного умнее, я мог бы найти это, но тогда это было не так. Мы вернемся к тому, что я мог бы сделать лучше, но сначала о прорыве, который привел к решению:

Прорыв: Установка точки прерывания в пределах предупреждения

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

Теперь, перезагрузив приложение, я смог проверить состояние Vue vm во время срабатывания предупреждения. Сделав это, я не увидел ничего очевидного… vm содержал filterBy, но оно выглядело как ожидаемая функция. Поэтому я пошел дальше в отладчике, и добрался до функции, которая вызвала предупреждение:

Ах-ха! Теперь мы можем непосредственно проверить метод, вызывающий предупреждение: он находится в объекте methods:

Ключ — это ссылка на местоположение источника. Он находился в комплекте vendors.app.js… если бы я правильно настроил sourcemapping в проекте, чтобы включить модули node, он бы указал мне прямо на источник, но даже без этого я мог бы прокрутить код, чтобы увидеть аннотацию webpack с указанием источника:

Эта функция исходила из vue2-filters, другого плагина сторонних разработчиков, который я установил, не слишком беспокоясь об этом. Этот плагин устанавливает набор общих фильтров, включая некоторые, которые реализованы как методы. Один из этих методов просто вызывал filterBy, и он переопределял свойство в vue-select. Вуаля! Вот и решение!

Быстрое решение, которое могло бы быть

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

Оказывается, если бы я проинспектировал объект $vm0, который был моим компонентом VSelect, вместо того, чтобы просто выполнять функцию filterBy, инструменты для разработчиков фактически позволили бы мне перейти к исходному коду.

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

Дополнительная информация и ресурсы

Надеюсь, вам понравилась эта «детективная история», и вы получили некоторые идеи, которые помогут вам отладить свои приложения Vue.js.

Если вы хотите самостоятельно изучить эту проблему отладки, я установил приложение для barebone с Nuxt 2.0, которое воспроизводит проблему в github здесь.

Все эти примеры отладки были выполнены с помощью инструментов для разработчиков Chrome и расширения Vue Devtools Chrome. Аналогичное расширение существует для Firefox, как и приложение Electron, которое будет работать в любой среде.

Автор: Kevin Ball

Источник: https://vuejsdevelopers.com/

Редакция: Команда webformyself.