Одна статья полностью разбирается в webpack devtool

Webpack
Одна статья полностью разбирается в webpack devtool

Зачем нужна исходная карта

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

  • Переводчик (Бабель)
  • Компилятор (TypeScript)
  • Минификаторы (UglifyJS)

Зачем? Поскольку обычно код, который мы запускаем в браузере, обрабатывается, обработанный код может быть далек от кода во время разработки, что затрудняет отладку разработки и онлайн-отладку. В это время в игру вступает Source Map, и с ее помощью браузер может напрямую найти код после преобразования в код до преобразования. В веб-пакете исходную карту можно настроить с помощью параметров devtool.

элемент конфигурации

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

Узнал на официальном сайте webpack стоимость devtoolЕсть 20+ видов.

Звучит пугающе, но, к счастью, у него есть установленный шаблон.

[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

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

понять качество

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

Так что же это?Он описывает содержимое исходного кода, которое мы видим при отладке..

Давайте посмотрим на его значение и значение

quality имея в виду
bundled code Модуль не отсоединен
generated code Модули разделения, код погрузчика без лечения
transformed code Разделение модулей, код обрабатывается загрузчиком
original source код, который вы написали сами
without source content Сгенерированная исходная карта не содержит sourcesContent
(lines only) Содержит информацию о строке, а не информацию о столбце

понимать инструменты разработки

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

特别提醒:指定devtool时,要与mode配合使用。

Во-первых, в приведенном выше шаблоне есть три категории ключевых слов:

  • встроенный, скрытый, eval
  • nosources
  • cheap[module]

Как говорится, практикаЕдинственный критерий проверки истиныЛучший способ научиться чему-то, это 🌰 попрактиковаться.

Вот простая демонстрация с двумя файлами, в которой основной файл main.js представляет файл a.js. Чтобы лучше имитировать реальную сцену, в веб-пакете также используется babel-loader для обработки js-файлов.

Подробности следующие:

Далее, давайте попрактикуемся в волне~

встроенный, скрытый, eval

Эти режимы являются взаимоисключающими и описывают, как вводится Source Map.

inline

Содержимое исходной карты вводится в файл js через base64.

hidden

В коде нет sourceMappingURL, и браузер автоматически не вводит исходную карту.

eval

Сгенерированный код смешивается с содержимым исходной карты и выводится через eval.

nosources

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

cheap[module]

Это ключевое слово используется для указания информации о отладке целостности

cheap

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

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

cheap-module

Не содержит информации столбца, исходный код является кодом на момент разработки

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

Как работают исходные карты

Спецификация исходной карты

Согласно спецификации Source Map v3 рекомендуемый формат:

{
    "version" : 3,
    "file": "out.js",
    "sourceRoot": "",
    "sources": ["foo.js", "bar.js"],
    "sourcesContent": [null, null],
    "names": ["src", "maps", "are", "fun"],
    "mappings": "A,AAAB;;ABCDE;"
}

Давайте объясним, что представляет собой каждый атрибут.

Атрибуты Нижний предел значения силы майнинга
version Версия файла исходной карты
file Имя файла, соответствующего исходной карте
sourceRoot Корневой каталог исходного файла, это значение будет добавлено перед каждым исходным файлом.
sources Список исходных файлов для маппинга
sourcesContent Список строк исходного кода, используемый для отображения исходных файлов при отладке, каждый элемент в списке соответствует источникам
names Имена переменных исходного файла и имена свойств для сопоставлений
mappings Информация о местонахождении

Браузер и исходная карта

Вот браузер Chrome в качестве примера (другие браузеры должны быть похожими~).

загрузить исходную карту

Браузер загружает исходную карту через sourceMappingRUL в файле js, и sourceMapping поддерживает две формы:путь к файлу или формат base64.

После загрузки исходной карты вы можете увидеть соответствующую информацию на вкладке «Источники» инструмента разработчика браузера.

Здесь мы сосредоточимся на объяснении файла карты вsourcesполя иsourcesContentполе.

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

Заглянем сюда через каштан, я добавил в sources файл hello.js, а в sourcesContent соответственно добавил контент hello~. Ниже показан результат после того, как браузер загрузит файл карты.

Подробное объяснение отображений

Просто подарите каштан 🌰:

源码:input.js
i am handsome  
you are ugly
转换后代码:output.js
i am handsome you are
ugly

Как мы записываем информацию об этой корреспонденции? Здесь вы можете обратиться кэта статья[1].

Информация о местоположении должна включать: выходное местоположение (Output location), исходный файл (Input), исходный код (Input location), исходный код.

Поэтому на основе каштанов выше, мы можем нарисовать следующую таблицу.

Output location Input Input location Character
L1, C0 index.js L1, C0 i
Л1, С2 index.js L1, C2 a
Л1, С3 index.js L1, C3 m
Л1, С5 index.js L1, C5 h
Л1, С6 index.js L1, C6 a
Л1, С7 index.js L1, C7 n
Л1, С8 index.js L1, C8 d
Л1, С9 index.js L1, C9 s
Л1, С10 index.js L1, C10 o
Л1, С11 index.js L1, C11 m
Л1, С12 index.js L1, C12 e
Л1, С14 index.js L2, C0 y
Л1, С15 index.js L2, C1 o
Л1, С16 index.js L2, C2 u
Л1, С18 index.js L2, C4 a
Л1, С19 index.js L2, C5 r
Л1, С20 index.js L2, C6 e
Л2, С0 index.js L2, C8 u
Л2, С1 index.js L2, C9 g
Л2, С2 index.js L2, C10 l
Л2, С3 index.js L2, C11 y

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

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

Точки оптимизации следующие:

  1. можно поставитьВходные файлы в список, чтобы индекс списка можно было использовать для представления информации о местоположении.
  2. Для исходного кодаНет необходимости записывать каждый символСоответствующая информация, нам нужно только записать имя переменной и атрибута (слово), вы можете использовать список, чтобы сохранить слово, информацию о местоположенииЗапишите только позицию первого символа словаВот и все.
  3. Информация о строке выходного файла относительно повторяется, поэтому вы можете использовать;Чтобы разделить каждую строку выходного кода, используйте,сегментировать информацию о положении каждого выходного кода.
  4. Каждое слово исходного кода может использоватьотносительное положение, эта информация о местоположении (числа) может быть меньше.

Таблица после оптимизации выглядит следующим образом:

sources: [index.js]
names: [i, am, handsome, you, are, ugly]
Output location Input index Input location Name index
Л1, С0 0 L1, C0 0
Л1, С+2 +0 L1, C+2 +1
Л1, С+3 +0 L1, C+3 +1
Л1, С+9 +0 L2, C-5 +1
Л1, С+4 +0 L2, C+4 +1
Л2, С-18 +0 L2, C+4 +1

В это время информация о местоположении может быть записана как

mappings: "0|0|1|0|0,2|0|1|2|1,3|0|1|3|1,9|0|2|-5|1,4|0|2|4|1;-18|0|2|4|1"
备注:
1. 数字使用分隔符“|”分割
2. 0|0|1|0|0代表 -> 0(输出单词列), 0(输入文件sources索引),10(输入单词行列),0(单词names索引)

Оптимизация с VLQ.

В приведенных выше сопоставлениях, поскольку каждая позиция не обязательно является числом, ее необходимо использовать|Разделитель для разделения чисел. Размер отображений можно значительно оптимизировать, если опустить разделитель. В настоящее время необходимо ввести VLQ (количества переменной длины).

VLQ характеризуется очень компактным представлением больших значений. ПринципИспользуйте 6 двоичных битов для представления символов, где старший бит указывает, является ли он непрерывным (0: прерывистый, 1: непрерывный), а младший бит указывает, является ли он положительным или отрицательным (0: положительный, 1: отрицательный).

Для двух каштанов 🌰🌰: рисунки 1 и -23.

数字:1
二进制:1
VLQ编码:000010
Base64 VLQ: C
数字:-23
绝对值:23
二进制:10111
VLQ编码:101111 000001
Base64 VLQ: vB

Здесь возьмите -23 сломать процесс поколения.

第一步:去23的二进制码 -> 10111
第二步:将10111分成两部分,第一部分是后四位,后面部分是五位为一部分 -> 1、0111 -> 00001、0111
第三步:按VLQ格式拼接 -> 101111 000001
其中,101111是 1【连续标识位】 + 0111 + 1【正负标识位】
000001是 0【连续标识位】+ 00001
第四步:对照Base64索引表(下表)

Наконец, давайте посмотрим, как выглядят приведенные выше сопоставления после оптимизации.

优化前:
mappings: "0|0|1|0|0,2|0|1|2|1,3|0|1|3|1,9|0|2|-5|1,4|0|2|4|1;-18|0|2|4|1"
优化后
mappings: "AACAA,EACEC,GACGC,SAELC,IAEIC,lBAEIC"

Как использовать в проекте

через изложенную выше теорию. У нас уже есть некоторое представление об элементах конфигурации source-map и devtool в webpack, давайте начнем с реальности и взглянем на проект.другая средав том, как должен быть настроен webpack.

Как рекомендуется WebPack?

Давайте посмотрим непосредственно на официальный сайт webpack.devtool[2]рекомендовать:

Development

Рекомендуемое использование:

  • eval
  • eval-source-map
  • eval-cheap-source-map
  • eval-cheap-module-source-map

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

devtool исходный уровень скорость наращивания информация столбца
eval Код обрабатывается webpack + загрузчик быстро +
eval-source-map исходный код медленный +
eval-cheap-source-map Код обрабатывается загрузчиком середина -
eval-cheap-module-source-map исходный код середина -

Production

Рекомендуемое использование:

  • none
  • source-map
  • hidden-source-map
  • nosources-source-map

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

devtool исходный уровень безопасность информация столбца
none - - -
source-map исходный код Браузер загрузит исходную карту, и исходный код будет открыт при отладке. +
hidden-source-map исходный код Файл карты создается, но браузер не загружает исходную карту. Может использовать файлы карт в сочетании с инструментами отчетов об ошибках. +
nosources-source-map исходный стек Без sourcesContent отладчик может видеть только информацию о модуле и информацию о строке, но не исходный код. -

Как настроен реальный проект

Просматривая проекты в команде проекта, среда разработки используетeval-cheap-module-source-map, и большинству производственных сред нужно знать только модуль и номер строки отчета об ошибке, поэтому они используютnosources-source-map.

наконец


Обратите внимание на «Блуждание по фронтенду» и получайте качественные статьи как можно скорее.

использованная литература

[1]

Source Maps under the hood: https://docs.microsoft.com/zh-cn/archive/blogs/davidni/source-maps-under-the-hood-vlq-base64-and-yoda#comment-626

[2]

webpack: https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/6/28/172f8f3771f18da1~tplv-t2oaga2asx-image.image