/ 

Логирование в JavaScript

Логирование — незаменимый инструмент в отладке JS кода. Расставьте логи в критические места и при возникновении ошибки вы сможете посмотреть что произошло в консоли. По логам вы увидите последовательность действий и поймете где произошла ошибка. Но обычно происходит по другому.

Вася следит за логами
Вася следит за логами

Разработчик Вася, использует console.log только когда код не работает. Он думает где это сломалось, и расставляет логи. Потом он перезагружает браузер, смотрит что сломалось не там и идет расставлять еще пачку console.log, а может даже и console.info.

В этом абстрактном Васе я узнаю себя пол года назад. Возможно, вы тоже. Этот подход работает, но можно лучше.

Почему так

Причин для такого поведения много:

  1. Этому не учат в школе/университете/на курсах. Там дают только базовые знания, да и преподаватели не всегда обладают нужной квалификацией.
  2. Если добавлять console.log на каждый чих, то открыв консоль вы ничего не поймете. Получится большая каша.
  3. Если не настроены sourcemap, ставить «точки остановки» долго и не все это умеют
  4. Мы так привыкли. Когда я изучал JavaScript, то в учебных примерах результат выводили через alert()
  5. В JavaScript раньше не хранили много логики. Вычислениями и отрисовкой html занимался сервер.

По данным http archive, средний размер JavaScript файла подключаемого на страницу увеличивается с каждым годом. Приложения разрастаются и становятся сложнее, особенно с приходом Single Page Application.

Как не засрать консоль

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

  1. Фильтрация по тексту
  2. Типы логов: .log, .warn, .info, .error
  3. Цвет у сообщения

Для логирования я рекомендую использовать библиотеку debug. Я буду использовать её в примерах далее.

Пример из жизни

Напишем модуль, который будет загружать гугл карты:

{
  'use strict'
  debug = window.debug('service:googlemaps')

  class GoogleMaps {
    constructor() {
      debug('constructor', this)
      this.load()
    }

    load() {
      return new Promise((resolve, reject) => {
        debug('loading:start')
        $.getScript("//maps.googleapis.com/maps/api/js", (data, textStatus) => {
          debug('loading:end', textStatus)

          if (textStatus != 'success') reject(textStatus)
          else resolve()
        })
      })
    }
  }

  GoogleMaps()
}

Чтобы сообщение появились в консоли — укажите какие логи показать. Установив localStorage.debug = '*' мы увидим все сообщения.

Логи модуля GoogleMaps
Логи модуля GoogleMaps

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

Как подключить себе

  1. Установите библиотеку через npm, bower или скачайте с github

    $ npm install debug --save
    # или
    $ bower install debug --save
    
  2. Добавьте файл в систему сборки перед другими модулями или вставьте через тег script

    <script src="./path/to/debug.js">
    
  3. Для каждого модуля объявите переменную для дебага. Значение будет добавляться к каждому логу с определенным цветом.

    debug = window.debug('service:googlemaps')
    
  4. Залогируйте что-нибудь

    debug('loading:start')
    
  5. Включите отображение логов в консоли

    localStorage.debug = '*'
    

После выполнения этих действий вы увидите логи в консоли и станете лучше контролировать происходящее в JavaScript. Если у вас раньше не было логирования в проекте, не стоит просить пару дней чтобы его настроить. Подключите библиотеку и когда будете рефакторить старый или писать новый модуль — добавьте логирование туда.

Дополнительный материал

О логировании и console.log рассказал Антон Шувалов выступая на конференции DUMB 2016 в секции FrontTalks.

Антон Шувалов — «Отладка кода в браузере»

Ссылки на записи выступлений с FrontTalks 2016 на хабре, а за прошлый год у меня в статье «Видео и презентации с конференции “FrontTalks” 2015».

⌘ ⌘ ⌘
Челендж JavaScript30
Фронтенд

Челендж JavaScript30

Обучающий курс JavaScript30. Тридцать заданий по Javascript с разбором решений

Код. Удаляем дубликаты из массива
Фронтенд

Код. Удаляем дубликаты из массива

Простые способы для ES5 и ES2015

jQuery.width() без округления
Фронтенд

jQuery.width() без округления

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

Код. Плейсхолдер для [contenteditable]
Фронтенд

Код. Плейсхолдер для [contenteditable]

Placeholder полифил для contenteditable элемента