Source maps что это
Введение в Javascript Source Maps
Вы когда-нибудь думали, как было бы здорово, если бы слитый в один файл и минифицированный яваскрипт код в production-окружении можено было удобно читать и даже отлаживать без ущерба производительности? Теперь это возможно, если использовать штуку под названием source maps.
Если коротко, то это способ связать минифицированный/объединённый файл с файлами, из которых он получился. Во время сборки для боевого окружения помимо минификации и объединения файлов также генерируется файл-маппер, который содержит информацию об исходных файлах. Когда производится обращение к конкретному месту в минифицированном файле, то производится поиск в маппере, по которому вычисляется строка и символ в исходном файле. Developer Tools (WebKit nightly builds или Google Chrome Canary) умеет парсить этот файл автоматически и прозрачно подменять файлы, как будто ведётся работа с исходными файлами. На момент написания (оригинальной статьи — прим. перев.) Firefox заблокировал развитие поддержки Source Map. Подробнее — на MozillaWiki Source Map.
Пример — правильное определение места в исходном коде
В этом примере можно ткнуть в любом месте textarea правой кнопкой и выбрать пункт «Get original location». При этом будет произведено обращение к файлу-мапперу с передачей строки и номера символа в минифицированном коде, и будет показан соответствующий кусок кода из исходного файла. В консоль будут выведены номер строки и номер символа в исходном файле и другая интересная информация.
Реальное использование
Прежде чем смотреть следующий пример, нужно активировать просмотр source maps в Chrome Canary или WebKit nightly, для этого в свойствах активировать пункт «Enable source maps» (см. скриншот)
Продолжим. Предыдущий пример был интересным, но как это можно использовать? Зайдите на dev.fontdragr.com настроенным браузером Google Chrome и вы увидите, что яваскрипты на странице не скомпилированы и можно смотреть отдельные js-файлы. Это всё благодаря использованию маппера, а на самом деле код на странице скомпилирован. Все ошибки, выводы в лог и точки останова будут маппиться на исходный код, и отлаживать код будет очень удобно. В итоге можно работать с production-сайтом как с тестовым.
Зачем вообще нужны Source Maps?
Google Web Toolkit (GWT) недавно добавил поддержку Source Maps и Ray Cromwell из GWT сделал отличный скринкаст, показывающий работу Source Map в действии.
Другой пример использует библиотеку Google Traceur, которая позволяет писать на ES6 (ECMAScript 6) и компилировать в ES3-совместимый код. Компилятор Traceur также генерирует source map. Посмотрите на пример использования особенностей ES6 (классов и traits), как если бы они поддерживались браузером нативно. Textarea в примере также позволяет писать ES6-код, который будет компилироваться на лету в ES3 и также будет создаваться файл-маппер.
Пример — можно написать код на ES6 и сразу посмотреть в отладчике
Как это работает?
Единственный пока компилятор/минификатор с поддержкой Source Map — Closure compiler (как при компиляции сгенерировать маппер — написано ниже). При минификации JavaScript будет создан и файл-маппер. Пока Closure compiler не добавляет в конец файла специальный комментарий для Google Chrome Canary dev tools о том, что доступен файл-маппер:
Такой комментарий позволяет браузеру искать нужное место в исходном файле, используя файл-маппер. Если идея использовать странные комментарии вам не нравится, то можно добавить к скомпилированному файлу специальный заголовок:
Как и комментарий, это скажет клиенту, где искать маппер для этого файла. Использование заголовка также позволяет работать с языками, которые не поддерживают однострочные комментарии.
Файл-маппер будет скачан только если включено свойство и открыта консоль. Ну и конечно нужно будет залить исходные файлы, чтобы они были доступны по указанным в маппере путям.
Как сгенерировать файл-маппер?
Как уже говорилось выше, нужен будет Closure compiler для минификаци, склейки и генерации файла-маппера для нужных JavaScript-файлов. Для этого нужно выполнить команду:
Внутреннее устройство Source Map
Чтобы лучше понять Source Map, возьмём для примера небольшой файл-маппер и подробно разберём, как устроена «адресация». Ниже приведён немного модифицированный пример из V3 spec:
BASE64 VLQ или как сделать Source Map маленьким
Потенциальные проблемы с XSSI
В спецификации говорится о возможных проблемах с внедрением XSS при использовании Source Map. Избавиться от неё можно, написав в начале своего map-файла » )]> «, чтобы сделать это js-файл невалидным и вызвать ошибку. WebKit dev tools уже умеет её забарывать:
Как видно, первые три символа обрезаются и производится проверка их на соответствие указанному в спецификации невалидному коду и в этом случае вырезается всё до следующего символа перевода строки.
@sourceURL и displayName в действии: eval и анонимные функции
Пример — пропущенный через eval код со сгенерированным именем
Вливайтесь
Есть очень длинное обсуждение по поддержке Source Map в CoffeeScript.
У UglifyJS также есть тикет про поддержку Source Map.
Вы можете помочь, если примете участие в обсуждении и выскажете мнение по поводу нужности поддержки Source Map. Чем больше будет инструментов, поддерживающих эту технологию, тем будет проще работать, так что требуйте её поддержки в вашем любимом OpenSource-проекте.
Source Map не идеален
Есть одна неприятность с использованием Source Map для нормальной отладки. Проблема заключается в том, что при попытке проверить значение аргумента или переменной, определённой в контексте исходного файла, контекст ничего не вернёт, т.к. он на самом деле не существует. Нужен какой-то обратный маппинг, чтобы проверить значение соответствующей переменной/аргумента в минифицированном коде и сопоставить его исходному коду.
Проблема решаемая, а при должном внимании к Source Map могут появиться ещё более интересные его применения.
Инструменты и ресурсы
Source Map — мощный инструмент для разработчика. Он позволяет держать production-код максимально сжатым, но при этом позволяет его отлаживать. Так же полезен для начинающих разработчиков, чтобы посмотреть код, написанный опытными разработчиками, чтобы поучиться правильному структурированию и написанию своего кода без необходимости продираться сквозь минифицированный код. Так чего же вы ждёте? Сгенерируйте Source Map для своего проекта!
Преимущества использования source map на проектах
При добавлении CSS в проект, обычной практикой является разделение таблицы стилей на несколько модулей или частей. Затем мы импортируем эти части вместе с другими в один индексный файл, используя директиву @import, после чего они будут собраны с помощью LESS препроцессора в один файл CSS. Вот здесь начинается проблема. Браузеры анализируют собранный CSS, а не ваши рабочие файлы, что в конечном итоге делает отладку стилей более сложной. Выяснить, из каких именно файлов получился собранный CSS, практически невозможно.
Проблему с отладкой можно решить, используя source maps. Source maps позволяют ассоциировать собранный код с исходным кодом вашего проекта и значительно облегчить его отладку. Давайте разберёмся, как добавить поддержку source maps в проект с LESS препроцессором.
Не видно, из какого LESS-файла берутся стили, есть только reference на собранный core.css файл. Нужно активировать source maps. Подключим source maps — для этого добавим в Gruntfile.js поддержку Source maps:
При запуске будет создан grunt, начнёт обновляться файл core.css.map, а в core.css в самый конец файла добавится строка:/*# sourceMappingURL=/assets/css/core.css.map*. Теперь в Chrome DevTools мы сможем просматривать исходники LESS вот так (в Firebug не работает, но может есть какие-то дополнения, если поискать):
т.е. видно прямой reference на blocks.less вместо ссылки на скомпилированный core.css.
Можно, конечно, обходиться и без source map, но на большом проекте с множеством LESS-файлов удобство работы с LESS будет ощутимо.
Source Maps 101
Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)
В современном рабочем процессе код, который мы имеем в наших средах разработки, значительно отличается от production кода, после его запуска посредством компиляции, минимизации, конкатенации или различных других процессов оптимизации.
Здесь вступают в игру source maps, указывая точное сопоставление в нашем production коде на исходный авторский код. В этом вводном учебнике мы рассмотрим простой проект и пропустим его через различные компиляторы JavaScript, чтобы поиграться с source maps в браузере.
Что такое Source Maps?
Source Maps предлагают не зависимый от языка способ сопоставления production кода с исходным кодом.
Исходные карты предлагают не зависимый от языка способ сопоставления производственного кода с исходным кодом, который был создан в вашей среде разработки. Когда мы в конечном счете смотрим на базу кода, сгенерированную и подготовленную к production, становится очень сложно найти то место, где происходит сопоставление строк с нашим исходным авторским кодом. Однако во время компиляции source map хранит эту информацию, поэтому, когда мы запрашиваем строку, она вернет нам точное местоположение в исходном файле! Это дает огромное преимущество разработчику, поскольку код становится читаемым и даже отлаживается!
В этом уроке мы рассмотрим очень простой код JavaScript и SASS, запустим их через различные компиляторы, а затем просмотрим исходные файлы в браузере с помощью исходных карт. Загрузите демо-файлы, и давайте начнем!
Браузеры
Обратите внимание, что при написании этой статьи Chrome (версия 23) поддерживает карты исходников JavaScript и даже карты SASS. Firefox также должен получить поддержку в ближайшем будущем, так как в настоящее время он находится в активной стадии разработки. Итак, давайте посмотрим, как мы можем использовать карты источников в браузере!
Source maps в Chrome
Во-первых, мы должны включить поддержку в Chrome, выполнив следующие простые шаги:
Настройка
Просмотрите простые файлы сценариев в простых JavaScript, TypeScript или CoffeeScript. Используя различные компиляторы JavaScript, мы создадим готовую для production версию, а также сгенерируем соответствующие карты.
В следующих разделах мы будем использовать пять различных способов создания скомпилированного и мини-скрипта script.js вместе с соответствующей картой. Вы можете либо попробовать все возможные варианты или просто выбрать компилятор, с которым вы уже знакомы. Эти варианты включают:
Вариант A : компилятор Closure
Когда мы открываем index.html в браузере и перейдем к Source панели в средствах разработчика, то будет ссылка только на оптимизированную версию script.closure.js ; у нас нет способа вернуть соотношение к нашему оригинальному, исходному файлу. Давайте создадим файл карты, выполнив следующую команду в каталоге scripts :
Кроме того, попробуйте использовать точки останова для отладки, но имейте в виду, что наблюдаемые выражения и переменные пока недоступны с картами. Надеюсь, они появятся в будущем!
Вариант B : задача GruntJS для JSMin
Если вы уже используете Grunt.js для процессов сборки, вам понадобится плагин Grunt для карт JSMin. Он не только оптимизирует ваш код, но также создаст карту!
Следующие шаги продемонстрируют, как создать оптимизированную версию script.js с плагином Grunt JSMin:
С Grunt и плагином, jsmin-sourcemap, процесс сборки создал два файла: оптимизированный файл сценария с URL-адресом исходного источника, а также карту. Для просмотра всех их в браузере вам потребуются они оба.
Вариант C : UglifyJSё
Вариант D : CoffeeScript Redux
Шаг 1: CoffeeScript для простого JavaScript
Перейдите в каталог «start» в командной строке. В следующих шагах мы сопоставим оптимизированный файл сценария с CoffeeScript:
Шаг 2: Обычный JavaScript для минификации-JavaScript
Вариант E : TypeScript
Шаг 1: TypeScript для простого JavaScript
Перейдите в каталог «scripts» из командной строки и выполните следующую команду:
Шаг 2: Обычный JavaScript для минифицированного JavaScript
Как и в примере с CoffeeScript, следующим шагом будет использование UglifyJS.
Наконец, убедитесь, что index.htm l ссылается на правильный файл сценария, scripts/script.typescript.min.js и откройте его в браузере!
Карты для SASS
Помимо JavaScript, в настоящее время Chrome также поддерживает карты SASS или SCSS. Для сопоставления исходника SASS исправьте несколько настроек в Chrome, а затем скомпилируем SASS в CSS с параметрами отладки:
Помимо просто просмотра файла SASS, если вы используете LiveReload в фоновом режиме и вносите изменения в файл SASS, страница также будет обновляться, чтобы отразить изменения. Например, давайте откроем проект в Firefox и проверим страницу, используя расширение Firebug.
Информация на карте
Дополнительные ресурсы
Карты по-прежнему очень активно развиваются, но уже есть некоторые большие ресурсы, доступные в Интернете. Обязательно рассмотрите следующие, если вы хотите узнать больше.
Заключение
Надеюсь, что описанное выше использование нескольких компиляторов продемонстрировало потенциал карт. Хотя их функциональность в настоящее время ограничена, мы надеемся, в будущем у нас будет полная возможность отладки, включая доступ к переменным и выражениям.
Русские Блоги
SourceMap учебник
Редактор рекомендует:FundebugСосредоточьтесь на JavaScript, апплетах WeChat, играх WeChat, Node.js и мониторинге ошибок Java в реальном времени. Это действительно очень хороший сервис по отслеживанию ошибок, которым пользуются многие крупные компании.
1. Введение
SourceMap Информационный файл, в котором хранится соответствие между исходным кодом и скомпилированным кодом.
В интерфейсной работе он в основном используется для решения проблем отладки в следующих трех аспектах:
а) после сжатия кода и запутывания
б. После компиляции в css или JS с использованием других языков, таких как sass и typeScript
В. После объединения нескольких файлов с помощью таких инструментов упаковки, как веб-пакет
В вышеупомянутых трех случаях мы не можем отлаживать так же легко, как исходный код при отладке, для этого требуется SourceMap, чтобы помочь нам преобразовать исходный код в консоли для отладки.
2. Принцип
Фактически, это пара ключ-значение JSON, которая использует кодировку VLQ и специальные правила для хранения информации о местоположении.
Если вас интересует логика, вы можете проверить эту статью, написанную мистером Руаном.«Детали JavaScript Source Map»
3. Как использовать
Эта вещь разработана Google, поэтому в настоящее время может работать только Chrome
Введите настройки режима разработчика
Найдите столбец Sources, установите флажок Allow JS SourceMap и css SourceMap (следует выбрать значение по умолчанию)
Используйте в Gulpgulp-sourcemaps Этот плагин реализован, сначала посмотрим на пример:
После открытия режима разработчика вы увидите окно, аналогичное приведенному выше, в разделе «Источники», чтобы объяснить, что обозначают эти три восклицательных знака:
Модуль рабочего пространства chrome, который предоставляет пространство для размещения локальных файлов в chrome и изменения кода локального файла одновременно с отладкой кода браузером.
4. Подробное объяснение API gulp-sourcemaps
Выше приведено требование к сжатию. Карта должна быть отделена и не должна соблюдаться в исходном файле, иначе сжатие будет больше, чем до сжатия. В настоящее время нам нужно больше понимать использование API.
Официальный файл немного грязный, я разобрался по моим собственным идеям:
Следующее объясняет четыре API по очереди, и использование gulp.src () и gulp.dest () зависит от моей статьи о Gulp.
Поскольку буквально означает API инициализации исходных карт, элементы конфигурации в нем:
исходные карты. API записи (url, <опция>) выходной конфигурации
Дайте больше способов определить исходный путь
Я попробовал это сам, похоже, не имеет никакого эффекта, и это не изменило ни адрес источника, ни выходной адрес. Пожалуйста, обратитесь к описанию следующего официального файла, чтобы попробовать это самостоятельно
The exported mapSources method gives full control over the source paths. It takes a function that is called for every source and receives the default source path as a parameter and the original vinyl file.
SourceMap только для JS и CSS для генерации полного сопоставления, по сравнению с пустым SourceMap по умолчанию, может предотвратить потерю информации.
5. gulp-sourcemaps доступные плагины
gulp-sourcemaps Не все плагины могут быть использованы, как указано выше, вам нужно проверить поддержкуwiki page
В настоящее время поддерживает три основные категории:
Конечно, вы также можете добавить поддержку плагинов напрямую, используйтеvinyl-sourcemaps-apply Я до сих пор не изучал создание плагинов, поэтому сейчас я не буду вдаваться в подробности, у меня будет возможность поговорить об этом позже.
Ну, выше приведен весь контент «SourceMap Tutorial», я надеюсь, что он может помочь вам, если у вас есть какие-либо вопросы, пожалуйста, оставьте сообщение
Source Maps: быстро и понятно
Механизм Source Maps используется для отображения исходных текстов программы на сгенерированные на их основе скрипты. Несмотря на то, что тема не нова и по ней уже написан ряд статей (например эта, эта и эта) некоторые аспекты все же нуждаются в прояснении. Представляемая статья представляет собой попытку упорядочить и систематизировать все, что известно по данной теме в краткой и доступной форме.
В статье Source Maps рассматриваются применительно к клиентской разработке в среде популярных браузеров (на примере, DevTools Google Chrome), хотя область их применения не привязана к какому-либо конкретному языку или среде. Главным источникам по Source Maps является, конечно, стандарт, хотя он до сих пор не принят (статус — proposal), но, тем не менее, широко поддерживается браузерами.
Работа над Source Maps была начата в конце нулевых, первая версия была создана для плагина Firebug Closure Inspector. Вторая версия вышла в 2010 и содержала изменения в части сокращения размера map-файла. Третья версия разработана в рамках сотрудничества Google и Mozilla и предложена в 2011 (последняя редакция в 2013).
В настоящее время в среде клиентской разработки сложилась ситуация, когда исходный код почти никогда не интегрируется на веб-страницу непосредственно, но проходит перед этим различные стадии обработки: минификацию, оптимизацию, конкатенацию, более того, сам исходный код может быть написан на языках требующих транспиляции. В таком случае, для целей отладки необходим механизм позволяющий наблюдать в дебаггере именно исходный, человекочитаемый код.
Для работы Source Maps необходимы следующие файлы:
Map-файл
Вся работа Source Maps основана на map-файле, который может выглядеть, например, так:
Обычно, имя map-файла складывается из имени скрипта, к которому он относится, с добавлением расширения «.map», bundle.js — bundle.js.map. Это обычный json-файл со следующими полями:
Загрузка Source Maps
Для того, чтобы браузер загрузил map-файл может быть использован один из следующих способов:
Таким образом, загрузив map-файл браузер подтянет и исходники из поля «sources» и с помощью данных в поле «mappings» отобразит их на сгенерированный скрипт. Во вкладке Sources DevTools можно будет найти оба варианта.
Для указания пути может использоваться пседопротокол file://. Также, в может быть включено все содержимое map-файла в кодировке Base64. В терминологии Webpack подобные Source Maps названы inline source maps.
Self-contained map-файлы
Код файлов-исходников можно включить непосредственно в map-файл в поле «sourcesContent», при наличии этого поля необходимость в их отдельной загрузке отпадает. В этом случае названия файлов в «sources» не отражают их реального адреса и могут быть совершенно произвольными. Именно поэтому, вы можете видеть во вкладке Sources DevTools такие странные «протоколы»: webpack://, ng:// и т.д
Mappings
Сущность механизма отображения состоит в том, что координаты (строка/столбец) имен переменных и функций в сгенерированном файле отображаются на координаты в соотвествующем файле исходного кода. Для работы механизма отображения необходима следующая информация:
(#1) номер строки в сгенерированном файле;
(#2) номер столбца в сгенерированном файле;
(#3) индекс исходника в «sources»;
(#4) номер строки исходника;
(#5) номер столбца исходника;
Все эти данные находятся в поле «mappings», значение которого — длинная строка с особой структурой и значениями закодированными в Base64 VLQ.
Строка разделена точками с запятой (;) на разделы, соответствующие строкам в сгенерированном файле (#1).
Каждый раздел разделен запятыми (,) на сегменты, каждый из которых может содержать 1,4 или 5 значений:
Каждое значение представляет собой число в формате Base64 VLQ. VLQ (Variable-length quantity) представляет собой принцип кодирования сколь угодно большого числа с помощью произвольного числа двоичных блоков фиксированной длины.
В Source Maps используются шестибитные блоки, которые следуют в порядке от младшей части числа к старшей. Старший 6-й бит каждого блока (continuation bit) зарезервирован, если он установлен, то за текущим следует следующий блок относящийся к этому же числу, если сброшен — последовательность завершена.
Поскольку в Source Maps значение должно иметь знак, для него также зарезервирован младший 1-бит (sign bit), но только в первом блоке последовательности. Как и ожидается, установленный sign бит означает отрицательное число.
Таким образом, если число можно закодировать единственным блоком, оно не может быть по модулю больше 15 (11112), так как в первом шестибитном блоке последовательности два бита зарезервированы: continuation бит всегда будет сброшен, sign бит будет установлен в зависимости от знака числа.
Шестибитные блоки VLQ отображаются на кодировку Base64, где каждой шестибитной последовательности соответствует определенный символ ASCII.
Декодируем число mE. Инверсируем порядок, младшая часть последняя — Em. Декодируем числа из Base64: E — 000100, m — 100110. В первом отбрасываем старший continuation бит и два лидирующих нуля — 100. Во втором отбрасываем старший continuation и младший sign биты (sign бит сброшен — число положительное) — 0011. В итоге получаем 100 00112, что соответствует десятичному 67.
Можно и в обратную сторону, закодируем 41. Его двоичный код 1010012, разбиваем на два блока: старшая часть — 10, младшая часть (всегда 4-битная) — 1001. К старшей части добавляем старший continuation бит (сброшен) и три лидирующих нуля — 000010. К младшей части добавляем старший continuation бит (установлен) и младший sign бит (сброшен — число положительное) — 110010. Кодируем числа в Base64: 000010 — C, 110010 — y. Инверсируем порядок и, в итоге, получаем yC.
Для работы с VLQ весьма полезна одноименная библиотека.