http://wm-monitoring.ru/ ')) {alert('Спасибо за то что установили нашу кнопку! =)');} else {alert('Очень жаль! =(');}"> http://wm-monitoring.ru/

Введение в исходные карты JavaScript

  1. Реальный мир
  2. Почему я должен заботиться об исходных картах?
  3. Как работает карта-источник?
  4. Как мне сгенерировать исходную карту?
  5. Анатомия исходной карты
  6. Base64 VLQ и небольшая исходная карта
  7. Потенциальные проблемы XSSI
  8. sourceURL и displayName в действии: Eval и анонимные функции
  9. Давайте сплотимся вместе
  10. Это не идеально
  11. вопросы

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

По сути, это способ сопоставить объединенный / свернутый файл обратно с непостроенным состоянием. Когда вы создаете для производства, наряду с минимизацией и объединением ваших файлов JavaScript, вы генерируете исходную карту, которая содержит информацию о ваших исходных файлах. Когда вы запрашиваете определенную строку и номер столбца в сгенерированном JavaScript, вы можете выполнить поиск на исходной карте, которая возвращает исходное местоположение. Инструменты разработчика (в настоящее время ночные сборки WebKit, Google Chrome или Firefox 23+) могут автоматически анализировать исходную карту и отображать ее так, как будто вы используете незакрепленные и не объединенные файлы.

Демо: Получить оригинальное местоположение

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

Убедитесь, что ваша консоль открыта, чтобы вы могли видеть результат

Реальный мир

Прежде чем просматривать следующую реальную реализацию Исходных карт, убедитесь, что вы включили функцию исходных карт в Chrome Canary или WebKit по ночам, щелкнув значок настройки на панели инструментов разработчика и отметив параметр «Включить исходные карты». Смотрите скриншот ниже.

Смотрите скриншот ниже

В Firefox 23+ исходные карты включены по умолчанию во встроенных инструментах разработчика. Смотрите скриншот ниже.

Смотрите скриншот ниже

Итак ... Это демо-запрос к исходной карте - это круто, но как насчет реального варианта использования? Взгляните на специальную сборку шрифта Dragr на dev.fontdragr.com в Chrome Canary, WebKit по ночам или Firefox 23+ с включенным сопоставлением исходного кода, и вы заметите, что JavaScript не скомпилирован, и вы можете увидеть все отдельные файлы JavaScript, на которые он ссылается. Это использует сопоставление исходного кода, но за кулисами фактически выполняется скомпилированный код. Любые ошибки, журналы и точки останова будут сопоставлены с кодом разработчика для потрясающей отладки! По сути, это создает у вас иллюзию того, что вы работаете с сайтом разработчиков.

Демо: Просмотр панели скриптов (с исходными картами) на fontdragr.com

Почему я должен заботиться об исходных картах?

В настоящее время сопоставление исходного кода работает только между несжатым / комбинированным JavaScript и сжатым / нескомбинированным JavaScript, но будущее выглядит блестящим, если говорить о языках, скомпилированных для JavaScript, таких как CoffeeScript, и даже о возможности добавления поддержки для препроцессоров CSS, таких как SASS или LESS. ,

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

  • CoffeeScript
  • ECMAScript 6 и выше
  • SASS / LESS и другие
  • Практически любой язык, который компилируется в JavaScript

Посмотрите на эту заставку CoffeeScript, отлаживаемую в экспериментальной сборке консоли Firefox:

Google Web Toolkit (GWT) недавно добавил поддержка Source Maps и Рэй Кромвель из команды GWT сделал потрясающий скриншот, показывающий поддержку карты источника в действии.

Другой пример, который я собрал, использует Google Traceur библиотека, которая позволяет писать ES6 (ECMAScript 6 или Next) и компилировать его в ES3-совместимый код. Компилятор Traceur также генерирует исходную карту. Взгляните на это демонстрация черты и классы ES6 используются так, как будто они изначально поддерживаются в браузере, благодаря исходной карте. Текстовая область в демоверсии также позволяет вам писать ES6, который будет скомпилирован на лету и сгенерировать исходную карту плюс эквивалентный код ES3.

Демонстрация: написать ES6, отладить его, посмотреть сопоставление источника в действии Демонстрация: написать ES6, отладить его, посмотреть сопоставление источника в действии

Как работает карта-источник?

Единственный компилятор / минификатор JavaScript, который на данный момент поддерживает генерацию карты источника, - это компилятор Closure. (Я объясню, как его использовать позже.) Как только вы объедините и минимизируете свой JavaScript, вместе с ним будет существовать файл исходной карты. В настоящее время компилятор Closure не добавляет в конце специальный комментарий, необходимый для обозначения инструментов разработчика браузеров, что карта источника доступна:

// # sourceMappingURL = / path / to / file.js.map

Это позволяет инструментам разработчика сопоставлять вызовы с их местоположением в исходных файлах. Ранее прагма комментария была // @, но из-за некоторых проблем с этим и IE условная компиляция комментариев решение было принято чтобы изменить его на // #. В настоящее время Chrome Canary, WebKit Nightly и Firefox 24+ поддерживают новую прагму комментариев. Это изменение синтаксиса также влияет sourceURL ,

Если вам не нравится идея странного комментария, вы можете установить специальный заголовок в скомпилированном файле JavaScript:

X-SourceMap: /path/to/file.js.map

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

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

Как мне сгенерировать исходную карту?

Как я уже говорил выше, вам нужно использовать Закрытие компилятора чтобы минимизировать, объединить и сгенерировать исходную карту для ваших файлов JavaScript. Команда выглядит следующим образом:

java -jar compiler.jar \ --js script.js \ --create_source_map ./script-min.js.map \ --source_map_format = V3 \ --js_output_file script-min.js

Двумя важными флагами команды являются --create_source_map и --source_map_format. Это необходимо, поскольку версия по умолчанию - V2, и мы хотим работать только с V3.

Анатомия исходной карты

Чтобы лучше понять исходную карту, мы возьмем небольшой пример файла исходной карты, который будет сгенерирован компилятором Closure, и более подробно рассмотрим, как работает раздел «Отображения». Следующий пример - небольшое отличие от V3 spec пример.

{версия: 3, файл: "out.js", sourceRoot: "", sources: ["foo.js", "bar.js"], имена: ["src", "maps", "are", " fun "], отображения:" AAgBC, SAAQ, CAAEA "}

Выше вы можете видеть, что исходная карта - это литерал объекта, содержащий много полезной информации:

  • Номер версии, на которой основана исходная карта
  • Имя файла сгенерированного кода (Ваш минифицированный / комбинированный производственный файл)
  • sourceRoot позволяет вам добавлять источники к структуре папок - это также метод экономии места
  • Источник содержит все имена файлов, которые были объединены
  • names содержит все имена переменных / методов, которые встречаются в вашем коде.
  • Наконец, свойство mappings - это то, где происходит волшебство, используя значения Base64 VLQ. Реальная экономия места делается здесь.

Base64 VLQ и небольшая исходная карта

Первоначально спецификация исходной карты содержала очень подробный вывод всех отображений, в результате чего исходная карта была примерно в 10 раз больше размера сгенерированного кода. Вторая версия уменьшила это примерно на 50%, а третья версия снова уменьшила его еще на 50%, так что для файла размером 133 КБ вы получите исходную карту размером ~ 300 КБ. Так как же они уменьшили размер при сохранении сложных отображений?

VLQ (Количество переменной длины) используется вместе с кодированием значения в значение Base64. Свойство mappings является супер большой строкой. Внутри этой строки находятся точки с запятой (;), которые представляют номер строки в сгенерированном файле. В каждой строке есть запятые (,), которые представляют каждый сегмент в этой строке. Каждый из этих сегментов имеет значение 1, 4 или 5 в полях переменной длины. Некоторые могут появляться дольше, но они содержат биты продолжения. Каждый сегмент основывается на предыдущем, что помогает уменьшить размер файла, поскольку каждый бит относительно его предыдущих сегментов.

Как я упоминал выше, каждый сегмент может иметь длину 1, 4 или 5. Эта диаграмма считается переменной длиной четыре с одним битом продолжения (g). Мы разберем этот сегмент и покажем, как исходная карта определяет исходное местоположение. Значения, показанные выше, являются чисто декодированными значениями Base64, для получения их истинных значений требуется еще немного обработки. Каждый сегмент обычно отрабатывает пять вещей:

  • Сгенерированный столбец
  • Оригинальный файл, который появился в
  • Исходный номер строки
  • Оригинальная колонка
  • И если доступно оригинальное имя.

Не каждый сегмент имеет имя, имя метода или аргумент, поэтому сегменты повсюду будут переключаться между четырьмя и пятью переменными длины. Значение g на диаграмме сегмента выше - это то, что называется битом продолжения, что позволяет проводить дальнейшую оптимизацию на этапе декодирования Base64 VLQ. Бит продолжения позволяет вам построить значение сегмента, чтобы вы могли хранить большие числа без необходимости хранить большое число, что является очень умной техникой экономии места, которая берет свое начало в формате midi.

Приведенная выше диаграмма AAgBC после дальнейшей обработки вернет 0, 0, 32, 16, 1 - 32 является битом продолжения, который помогает построить следующее значение 16. B, чисто декодированный в Base64, равен 1. Таким образом, используются важные значения: 0, 0, 16, 1. Затем это позволяет нам узнать, что строка 1 (строки учитываются с помощью точки с запятой) столбца 0 сгенерированного файла отображается в файл 0 (массив файлов 0 равен foo.js), строка 16 в колонка 1.

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

Чтобы правильно понять, как мы получаем значение 16 из B, нам нужно иметь базовые знания о побитовых операторах и как работает спецификация для отображения источника. Предыдущая цифра g помечается как бит продолжения путем сравнения цифры (32) и VLQ_CONTINUATION_BIT (двоичный код 100000 или 32) с помощью побитового оператора AND (&).

32 & 32 = 32 // или 100000 | | V 100000

Это возвращает 1 в каждой позиции бита, где они есть. Таким образом, декодированное значение Base64 33 и 32 вернет 32, поскольку они разделяют только 32-битное расположение, как вы можете видеть на приведенной выше диаграмме. Это затем увеличивает бит значение сдвига на 5 для каждого предыдущего бита продолжения. В приведенном выше случае он сдвигался только на 5 раз, поэтому сдвиг влево 1 (B) на 5.

1 << 5 // 32 // Сдвиг бита на 5 точек ______ | | VV 100001 = 100000 = 32

Затем это значение преобразуется из значения со знаком VLQ путем смещения вправо числа (32) на одну точку.

32 >> 1 // 16 // или 100000 | | V 010000 = 16

Итак, у нас это есть: вот как вы превращаете 1 в 16. Это может показаться слишком сложным процессом, но как только цифры начинают расти, это имеет больше смысла.

Потенциальные проблемы XSSI

В спецификации упоминаются проблемы включения межсайтовых скриптов, которые могут возникнуть из-за использования исходной карты. Чтобы смягчить это, рекомендуется предварительно добавить первую строку вашей исходной карты с помощью ")]}", чтобы преднамеренно сделать недействительным JavaScript, чтобы вызвать синтаксическую ошибку. Инструменты разработчика WebKit могут справиться с этим уже.

if (response. slice (0, 3) === ")]}") {response = response. подстрока (response. indexOf ('\ n')); }

Как показано выше, первые три символа нарезаются, чтобы проверить, соответствуют ли они синтаксической ошибке в спецификации, и если это так, удаляются все символы, приводящие к первому объекту новой строки (\ n).

sourceURL и displayName в действии: Eval и анонимные функции

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

Первый помощник выглядит очень похоже на свойство // # sourceMappingURL и на самом деле упоминается в спецификации карты источника V3. Включив в свой код следующий специальный комментарий, который будет пропущен, вы можете называть проповеди, чтобы они выглядели как более логичные имена в ваших инструментах разработки. Посмотрите простую демонстрацию с использованием компилятора CoffeeScript: Демонстрация: Посмотрите, как eval () показывает код в виде скрипта через sourceURL

// # sourceURL = sqrt.coffee // # sourceURL = sqrt

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

Демонстрация: именованные функции через displayName (только для Webkit Nightly)

btns [0]. addEventListener ("click", function (e) {var fn = function () {console. log ("Вы нажали номер кнопки: 1");}; fn. displayName = "Анонимная функция кнопки 1"; вернуть fn () ; }, ложный ); btns [0]

При профилировании вашего кода в инструментах разработки будет отображаться свойство displayName, а не что-то вроде (анонимно). Однако displayName в значительной степени мёртв в воде и не попадет в Chrome. Но все надежды не потеряны, и было предложено гораздо лучшее предложение под названием debugName ,

На момент написания статьи eval naming доступно только в браузерах Firefox и WebKit. Свойство displayName доступно только в ночных WebKit.

Давайте сплотимся вместе

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

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

Много инструменты генерировать исходные карты, включая компилятор coffeescript. Я считаю это спорным вопросом сейчас.

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

Это не идеально

Одна из причин, по которой Source Maps сейчас не обслуживается, - это смотреть выражения. Проблема состоит в том, что попытка проверить аргумент или имя переменной в текущем контексте выполнения ничего не даст, так как она на самом деле не существует. Это потребует некоторого обратного сопоставления для поиска реального имени аргумента / переменной, которую вы хотите проверить, по сравнению с фактическим именем аргумента / переменной в скомпилированном JavaScript.

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

вопросы

Относительно недавно JQuery 1,9 добавлена ​​поддержка исходных карт при обслуживании официальных CDN. Он также указал специфическая ошибка когда комментарии условной компиляции IE (// @ cc_on) используются перед загрузкой jQuery. С тех пор совершить чтобы смягчить это, поместив sourceMappingURL в многострочный комментарий. Урок, который нужно выучить, не использовать условный комментарий.

Это с тех пор был адресован с изменением синтаксиса на // #.

Вот некоторые дополнительные ресурсы и инструменты, которые вы должны проверить:

  • У Ника Фицджеральда есть вилка UglifyJS с поддержкой карты источника
  • У Пола Айриша есть удобный маленький демонстрация демонстрируя исходные карты
  • Проверьте набор изменений WebKit, когда это упал
  • Набор изменений также включал тест макета который начал всю эту статью
  • Мозилла имеет ошибка Вы должны следить за состоянием исходных карт во встроенной консоли
  • Конрад Ирвин написал супер полезно жемчужина исходной карты для всех пользователей Ruby
  • Некоторое дальнейшее чтение на Eval Naming и свойство displayName
  • Вы можете проверить Закрытие источника для создания исходных карт
  • Есть несколько скриншотов и разговоры о поддержке GWT исходные карты

Исходные карты - очень мощная утилита в наборе инструментов разработчика. Очень полезно иметь возможность поддерживать ваше веб-приложение легким, но легко отлаживаемым. Это также очень мощный инструмент обучения для начинающих разработчиков, позволяющий увидеть, как опытные разработчики структурируют и пишут свои приложения без необходимости разбираться с нечитаемым минимизированным кодом. Чего ты ждешь? Начните создавать исходные карты для всех проектов сейчас!

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