1. Что такое исходная карта
С точки зрения непрофессионала,Source Map
Это информационный файл, в котором хранится информация о местоположении после упаковки и преобразования кода, что по сути являетсяjson
Файл описания поддерживает отношения сопоставления кода до и после упаковки. оSource Map
Объяснение можно увидеть нижеIntroduction to JavaScript Source Maps.
Наш онлайн-код, как правило, упакован, и если онлайн-код сообщает об ошибке, его отладка будет очень трудоемкой, как в следующем примере:
Используйте инструменты для упаковкиWebpack
, скомпилируйте этот фрагмент кода
console.log('source map!!!')
console.log(a); //这一行肯定会报错
Эффект после открытия браузера:
После нажатия войти в файл ошибки:
Невозможно найти конкретное место и причину этого, поэтому в настоящее времяSource Map
Эффект наступает,Webpack
В коде сборки включитеSource Map
:
Затем повторно выполните сборку и снова откройте браузер:
Можно обнаружить, что конкретное место ошибки может быть успешно обнаружено, чтоSource Map
эффект. Необходимо отметить, что,Source Map
нетWebpack
Уникальные, другие инструменты упаковки также поддерживаютSource Map
, инструмент упаковки просто преобразуетSource Map
Эта технология внедряется через конфигурацию. Об инструменте упаковки будет введение ниже.
2. Роль исходной карты
Вышеприведенный случай как разSource Map
Первый опыт, теперь поговорим о его роли и зачем он нам нуженSource Map
?
Учитель Руан ИфэнПодробная карта исходного кода JavaScriptОбратите внимание, что сценарии JavaScript становятся все более и более сложными. Большая часть исходного кода (особенно различные библиотеки функций и фреймворки) должна быть преобразована, прежде чем ее можно будет поместить в производственную среду.
Обычное преобразование исходного кода, в основном в следующих трех ситуациях:
- сжать, уменьшить размер
- Объедините несколько файлов, чтобы уменьшить количество HTTP-запросов.
- Другие языки компилируются в JavaScript
Во всех трех случаях фактически работающий код отличается от кода разработки, отладки (debug
) становится затруднительным, поэтому необходимоSource Map
. В сочетании с приведенным выше примером, даже если код упакован, можно найти конкретное место ошибки, что заставляет насdebug
Код сделан легко и просто, этоSource Map
проблема, которую вы хотите решить.
3. Как создать исходную карту
Различные основные интерфейсные инструменты управления задачами и инструменты упаковки поддерживают генерациюSource Map
.
3.1 UglifyJS
UglifyJS
это инструмент командной строки для сжатияJavaScript
код
УстановитьUglifyJS
:
npm install uglify - js - g
Одновременная генерация сжатого кодаSource Map
:
uglifyjs app.js - o app.min.js--source - map app.min.js.map
Source Map
Связанные параметры:
--source - map Source Map的文件的路径和名称
--source - map - root 源文件的路径
--source - map - url //#sourceMappingURL的路径。 默认为--source-map指定的值。
--source - map - include - sources 是否将源代码的内容添加到sourcesContent数组
--source - map - inline 是否将Source Map写到压缩代码的最后一行
-- in -source - map 输入Source Map, 当源文件已经经过变换时使用
3.2 Grunt
Grunt
даJavaScript
инструмент сборки проекта
настроитьgrunt-contrib-uglify
плагин для генерацииSource Map
:
grunt.initConfig({
uglify: {
options: {
sourceMap: true
}
}
});
использоватьgrunt-usemin
При упаковке исходного кодаgrunt-usemin
будет вызываться последовательноgrunt-contrib-concatа такжеgrunt-contrib-uglifyУпакуйте и сожмите исходный код. Итак, все нужно настроить:
grunt.initConfig({
concat: {
options: {
sourceMap: true
}
},
uglify: {
options: {
sourceMap: true,
sourceMapIn: function(uglifySource) {
return uglifySource + '.map';
},
}
}
});
3.3 Gulp
Gulp
даJavaScript
инструмент сборки проекта
использоватьgulp-sourcemapsгенерироватьSource Map
:
var gulp = require('gulp');
var plugin1 = require('gulp-plugin1');
var plugin2 = require('gulp-plugin2');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('dist'));
});
3.4 SystemJS
SystemJS
загрузчик модулей
использоватьSystemJS Build ToolгенерироватьSource Map
:
builder.bundle('myModule.js', 'outfile.js', {
minify: true,
sourceMaps: true
});
-
sourceMapContents
Возможность указать, следует ли писать исходный кодSource Map
документ
3.5 Webpack
Webpack
Это интерфейсный инструмент упаковки (этот инструмент упаковки будет использоваться во всех случаях в этой статье). в его конфигурационном файлеwebpack.config.js
установить вdevtoolгенерироватьSource Map
документ:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
devtool: "source-map"
};
-
devtoolСуществует более 20 различных значений, которые генерируют различные типы
Source Map
, который можно настроить по мере необходимости. Подробно он будет представлен ниже и не будет повторяться здесь.
3.6 Closure Compiler
использоватьClosure Compilerгенерировать
4. Как использовать исходную карту
генерироватьSource Map
После этого обычно используется для отладки в браузере, при условии, что эту функцию нужно включить, чтобыChrome
Например:
Откройте инструменты разработчика и найдитеSettins
:
Проверьте следующие два варианта:
Возвращаясь к приведенному выше случаю снова, файл исходного кода становитсяindex.js
, щелкните, чтобы ввести и отобразить настоящий исходный код, что означает, что он был успешно открыт и использован.Source Map
Пять, принцип работы Source Map
Тем не менее в приведенном выше случае после выполнения упаковки сгенерированныйdist
папка, открытьdist/bundld.js
:
Вы можете увидеть это примечание в конце:
//# sourceMappingURL=bundle.js.map
Именно из-за этого комментария файлSource Map
адрес, браузер может правильно найти местоположение исходного кода.sourceMappingURL
направлениеSource Map
документURL
.
Помимо этого пути,MDNуказал, что черезresponse header
изSourceMap: <url>
поле для указания.
> SourceMap: /path/to/file.js.map
dist
папка, кромеbundle.js
а такжеbundle.js.map
, этот файлSource Map
файл тожеsourceMappingURL
указалURL
-
version
:Source map
версия, на данный моментv3
. -
sources
: файл до преобразования. Этот элемент представляет собой массив, указывающий, что может быть несколько слияний файлов. -
names
: Все имена переменных и свойств перед преобразованием. -
mappings
: Строка, которая записывает информацию о местоположении, которая будет описана ниже. -
file
: преобразованное имя файла. -
sourceRoot
: Каталог, где файл перед преобразованием. Если файл перед преобразованием в тот же каталог, это пусто. -
sourcesContent
: Исходное содержимое файла до преобразования.
5.1 О версии исходной карты
в 2009Google
В статье, во введенииCloure Compiler
час,Google
Также воспользовался запуском средства отладки:Firefox
плагинClosure Inspector
, чтобы облегчить отладку скомпилированного кода. ЭтоSource Map
Первое поколение этого!
You can use the compiler with Closure Inspector , a Firebug extension that makes debugging the obfuscated code almost as easy as debugging the human-readable source.
В 2010 году во втором поколении именноClosure Compiler Source Map 2.0
середина,Source Map
общепризнанныйJSON
Формат и другие стандарты уже почти сформировались. Самая большая разница в том,mapping
алгоритм тожеSource Map
ключевой адрес. во втором поколенииmapping
Использовалbase 64
кодирования, но алгоритм имеет доход и расход с текущим, поэтому сгенерированный.map
Гораздо больше, чем сейчас.
В 2011 году было выпущено третье поколение.Source Map Revision 3 ProposalОн вышел, и это то, что мы используем сейчасSource Map
версия. Из названия документа текущийSource Map
отстраненныйClousre Compiler
Эволюция на независимую, а также получил поддержку браузера. Эта версия сравнивается со главным изменением второго поколенияmapping
Конденсация алгоритма с использованиемVLQгенерация кодаbase64бывшийmapping
, значительно уменьшается.map
Размер файла.
Source Map
Самое забавное в истории разработки то, что она разрабатывалась как вспомогательный инструмент. Ведь цель его помощи снижается, но он стал основным корпусом техники и прописан в браузере.
Исходный файл исходной карты, сгенерированный Source Map V1, примерно в 10 раз больше, чем преобразованный файл. Исходная карта V2 уменьшает его на 50%, а V3 уменьшает на 50% на основе V2. Итак, теперь размер файла исходной карты, соответствующего файлу размером 133 КБ, составляет около 300 КБ.
5.2 О свойстве сопоставления
Во избежание помех измените регистр на следующий без ошибок:
var a = 1;
console.log(a);
После упаковки и компиляцииbundle.js
документ:
/******/
(() => { // webpackBootstrap
var __webpack_exports__ = {};
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
var a = 1;
console.log(a);
/******/
})();
//# sourceMappingURL=bundle.js.map
упаковано скомпилированоbundle.js.map
документ:
{
"version": 3,
"sources": [
"webpack://learn-source-map/./src/index.js"
],
"names": [],
"mappings": "AAAA;AACA,c",
"file": "bundle.js",
"sourcesContent": [
"var a = 1;\r\nconsole.log(a);"
],
"sourceRoot": ""
}
можно увидетьmappings
Стоимость имущества составляет:AAAA; AACA, c
, Чтобы прояснить эту вещь, вам нужно сначала объяснить ее структуру. Вот строка, она разбита на три слоя:
- Первый слойкорреспонденция строки, представленный точкой с запятой (;), каждая точка с запятой соответствует строке преобразованного исходного кода. Таким образом, содержимое перед первой точкой с запятой соответствует первой строке исходного кода и так далее.
- Второй слойместонахождение корреспонденция, представленный запятыми (, ), где каждая запятая соответствует позиции в преобразованном исходном коде. Следовательно, содержимое до первой запятой соответствует первой позиции исходного кода строки и так далее.
- Третий слойпреобразование позиции,кVLQ-кодированиеПредставляет расположение исходного кода перед преобразованием, соответствующим этому местоположению.
Вернувшись к исходному коду, вы можете проанализировать:
- Поскольку в исходном коде две строки, перед и после точки с запятой стоит точка с запятой для обозначения первой и второй строк. который
mappings
серединаAAAA
а такжеAACA,c
. - Вторая строка после точки с запятой - это код
console.log(a);
Его можно разделить на две позиции, а именноconsole
а такжеlog(a)
, поэтому стоит запятая. которыйAACA,c
серединаAACA
а такжеc
.
Подводя итог, этоПреобразованный исходный код разделен на две строки, первая строка имеет одну позицию, а вторая строка имеет две позиции..
Что касается этогоAAAA
,AAcA
Откуда пришли письма, вы можете обратиться к г-ну Жуань Ифэну.Подробная карта исходного кода JavaScriptЕсть подробное введение. Собственное понимание автора таково:
AAAA
а такжеAAcA
так же какc
Все они представляют позицию.Обычно каждая позиция состоит из букв 5. Значения 5 букв:
- Первый бит указывает, в каком столбце (преобразованного кода) находится эта позиция.
- Второй бит указывает, какому файлу в атрибуте sources принадлежит это местоположение.
- Третий бит указывает, какой строке кода принадлежит эта позиция до преобразования.
- Четвертая цифра указывает, к какому столбцу кода до конвертации относилась эта позиция.
- Пятый бит указывает, какой переменной в атрибуте name принадлежит эта позиция.
Здесь после конвертации максимум 4 буквы, потому что нетnames
Атрибуты.
Доступно в любом местеVLQ-кодированиеПреобразуйте, чтобы сформировать отношение сопоставления. допустимыйэтот сайтКонвертируйте тест сами, будетAAAA; AACA, c
Преобразованный результат:
Можно получить два набора данных:
[0, 0, 0, 0]
[0, 0, 1, 0], [14]
номера взяты из0
начни, займи местоAAAA
Например, после преобразования получаем[0, 0, 0, 0]
, поэтому значения представителей таковы:
- Сжать первый столбец кода.
- Первый файл исходного кода, т.е.
index.js
. - Первая строка исходного кода.
- исходный код первый столбец
Благодаря приведенному выше анализу мы можем узнать, что в исходном кодеvar a = 1;
В упакованном файле, т.е.bundle.js
конкретное место.
6. Исходная карта в Webpack
описано вышеSource Map
функция, принцип и т. Теперь поговорим об инструментах для упаковки.WebPack
средняя параSource Map
Приложение, ведь мы в разработке, без него не обойтись.
Как было сказано выше, необходимо толькоwebpack.config.js
конфигурация в файлеdevtool
просто используйтеSource Map
,этоdevtool
Каковы конкретные значения, вы можете обратиться кwebpack devtool
, официальный список из 20 типов, конечно, мы не можем запомнить их все, мы можем вспомнить несколько ключевых:
Предлагаются следующие 7 вариантов:
- source-map:внешний. Вы можете просмотреть точную информацию о коде ошибки и месте ошибки в исходном коде.
-
inline-source-map: в линию. генерировать только один встроенный
Source Map
, вы можете просмотреть точную информацию о коде ошибки и местоположении ошибки в исходном коде. - hidden-source-map:внешний. Вы можете просмотреть точную информацию о коде ошибки, но вы не можете отследить ошибку исходного кода и можете только указать место ошибки кода после сборки.
-
eval-source-map: в линию. Каждый файл генерирует соответствующий
Source Map
, все вeval
, вы можете просмотреть точную информацию о коде ошибки и местонахождение ошибки в исходном коде. - nosources-source-map:внешний. Вы можете просмотреть причину ошибки с кодом ошибки, но вы не можете просмотреть точную информацию о коде ошибки, и нет информации об исходном коде.
- cheap-source-map:внешний. Вы можете просмотреть точную информацию о коде ошибки и местоположении ошибки исходного кода, только ошибка может быть точной для всей строки, игнорируя столбец.
-
cheap-module-source-map:внешний. Может ли код ошибки указывать точную информацию и местоположение ошибки исходного кода,
module
присоединюсьloader
изSource Map
.
Разница между встроенным и внешним:
- файлы, созданные извне (
.map
), встроенный нет. - Встроенные сборки быстрее.
Следующие 7 типов демонстрируются на конкретных примерах:
Во-первых, измените регистр на состояние ошибки.Чтобы отразить ситуацию в столбце, измените исходный код следующим образом:
console.log('source map!!!')
var a = 1;
console.log(a, b); //这一行肯定会报错
6.1 source-map
devtool: 'source-map'
После компиляции вы можете просмотретьТочная информация о коде ошибки и местонахождение ошибки в исходном коде:
генерируется.map
документ:
6.2 inline-source-map
devtool: 'inline-source-map'
После компиляции вы можете просмотретьТочная информация о коде ошибки и местонахождение ошибки в исходном коде:
но не генерируется.map文件
, но сbase64
вставлен в формуsourceMappingURL
середина:
6.3 hidden-source-map
devtool: 'hidden-source-map'
После компиляции вы можете просмотретьКод ошибки точен, но местоположение исходного кода не видно:
генерируется.map
документ:
6.4 eval-source-map
devtool: 'eval-source-map'
После компиляции вы можете просмотретьТочная информация о коде ошибки и местонахождение ошибки в исходном коде:
но не генерируется.map文件
, но вeval函数
в том числеsourceMappingURL
:
6.5 nosources-source-map
devtool: 'nosources-source-map'
После компиляции вы можете просмотретьНевозможно просмотреть точное местоположение кода ошибки и местоположение ошибки исходного кода, и можно только подсказать причину ошибки:
генерируется.map
документ:
6.6 cheap-source-map
devtool: 'cheap-source-map'
После компиляции вы можете просмотретьТочная информация кода ошибки и местонахождение ошибки исходного кода, но без учета определенных столбцов (因为是b导致报错
):
генерируется.map
документ:
6.7 cheap-module-source-map
из-за необходимостиmodule
, так что случай возрастаетloader
:
module: {
rules: [{
test: /\.css$/,
use: [
// style-loader:创建style标签,将js中的样式资源插入进去,添加到head中生效
'style-loader',
// css-loader:将css文件变成commonjs模块加载到js中,里面内容是样式字符串
'css-loader'
]
}]
}
существуетsrc
новый каталогindex.css
файл, добавьте код стиля:
body {
margin: 0;
padding: 0;
height: 100%;
background-color: pink;
}
затем вsrc/index.js
Представленindex.css
:
//引入index.css
import './index.css';
console.log('source map!!!')
var a = 1;
console.log(a, b); //这一行肯定会报错
Исправлятьdevtool
:
devtool: 'cheap-module-source-map'
После упаковки откройте браузер, стиль вступит в силу, объяснитеloader
Введен успешно. может просматриватьТочная информация кода ошибки и местонахождение ошибки исходного кода, но без учета определенных столбцов (因为是b导致报错
):
генерируется.map
файл тем временем будетloader
Информация также упакована вместе:
6.8 Резюме
(1)среда разработки: необходимо учитывать высокую скорость и более удобную отладку.
- высокоскоростной(
eval
>inline
>cheap
>... )eval-cheap-souce-map
eval-source-map
- Отладка более дружелюбна
souce-map
cheap-module-souce-map
cheap-souce-map
В итоге получаются два лучших решения --> eval-source-map (высокая целостность, быстрая встроенная скорость) / eval-cheap-module-souce-map (подсказка об ошибке игнорирует столбцы, но содержит другую информацию, встроенная скорость быстрая)
(2)Производственная среда: вам нужно подумать, следует ли скрывать исходный код или нет, и должна ли отладка быть более удобной.
- Встраивание сделает код больше, поэтому нет необходимости встраивать в производственной среде.
- скрыть исходный код
-
nosources-source-map
Все скрыто (упакованный код и исходный код) -
hidden-source-map
Скройте только исходный код, он выдаст сообщение об ошибке кода после сборки.
-
В итоге получаются два лучших решения --> source-map (наиболее полная)/cheap-module-souce-map (ошибка предлагает целую строку игнорировать столбцы)
7. Резюме
Source Map
Это важно в нашем ежедневном процессе разработки, это может помочь нам отлаживать и находить ошибки. Хотя это включает в себя много точек знаний, таких как:VLQ,base64и т. д., но основное внимание мы уделяем тому, как это работает, и таким инструментам упаковки, какwebpack
ЭквивалентSource Map
Приложения.
Source Map
Очень мощный, не только используется в ежедневной разработке, но и может делать больше вещей, таких как性能异常监控平台
. НапримерFunDebugЭтот веб-сайт черезSource Map
Восстановите сжатый код в производственной среде, предоставьте полную информацию о стеке, точно определите местонахождение исходного кода ошибки и помогите пользователям быстро исправитьBug
, таких случаев гораздо больше.
Короче говоря, учусьSource Map
очень нужно.