Карты исходного кода — важнейший инструмент современной веб-разработки, который значительно упрощает отладку. На этой странице рассматриваются основы карт исходного кода, способы их создания и улучшения возможностей отладки.
Необходимость исходных карт
Ранние веб-приложения создавались с низкой сложностью. Разработчики разместили файлы HTML, CSS и JavaScript непосредственно в Интернете.
Более современным и сложным веб-приложениям в рабочем процессе разработки могут потребоваться различные инструменты. Например:
- Языки шаблонов и препроцессоры HTML: Pug , Nunjucks , Markdown .
- Препроцессоры CSS: SCSS , LESS , PostCSS .
- Фреймворки JavaScript: Angular , React , Vue , Svelte .
- Мета-фреймворки JavaScript: Next.js , Nuxt , Astro .
- Языки программирования высокого уровня: TypeScript , Dart , CoffeeScript .
Этим инструментам требуется процесс сборки для преобразования вашего кода в стандартные HTML, JavaScript и CSS, понятные браузерам. Также распространенной практикой является оптимизация производительности путем минимизации и объединения этих файлов с помощью такого инструмента, как Terser .
Например, используя инструменты сборки, мы можем перенести и сжать следующий файл TypeScript в одну строку JavaScript. Вы можете попробовать это сами в этой демо-версии на GitHub .
/* A TypeScript demo: example.ts */
document.querySelector('button')?.addEventListener('click', () => {
const num: number = Math.floor(Math.random() * 101);
const greet: string = 'Hello';
(document.querySelector('p') as HTMLParagraphElement).innerText = `${greet}, you are no. ${num}!`;
console.log(num);
});
Сжатая версия будет:
/* A compressed JavaScript version of the TypeScript demo: example.min.js */
document.querySelector("button")?.addEventListener("click",(()=>{const e=Math.floor(101*Math.random());document.querySelector("p").innerText=`Hello, you are no. ${e}!`,console.log(e)}));
Однако сжатие кода может затруднить отладку. Карты исходного кода могут решить эту проблему: сопоставляя скомпилированный код обратно с исходным кодом, они могут помочь вам быстро найти источник ошибки.
Создание исходных карт
Исходные карты — это файлы, имена которых заканчиваются на .map
(например, example.min.js.map
styles.css.map
). Их можно создать с помощью большинства инструментов сборки, включая Vite , webpack , Rollup , Parcel и esbuild .
Некоторые инструменты по умолчанию включают исходные карты. Другим может потребоваться дополнительная настройка для их создания:
/* Example configuration: vite.config.js */
/* https://vitejs.dev/config/ */
export default defineConfig({
build: {
sourcemap: true, // enable production source maps
},
css: {
devSourcemap: true // enable CSS source maps during development
}
})
Понять исходную карту
Чтобы облегчить отладку, эти файлы сопоставления исходного кода содержат важную информацию о том, как скомпилированный код сопоставляется с исходным кодом. Вот пример исходной карты:
{
"mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
"sources": ["src/script.ts"],
"sourcesContent": ["document.querySelector('button')..."],
"names": ["document","querySelector", ...],
"version": 3,
"file": "example.min.js.map"
}
Чтобы понять каждое из этих полей, вы можете прочитать спецификацию исходной карты или Анатомию исходной карты .
Наиболее важной частью исходной карты является поле mappings
. Он использует строку в кодировке VLQ base 64 для сопоставления строк и местоположений в скомпилированном файле с соответствующим исходным файлом. Вы можете просмотреть это сопоставление с помощью визуализатора исходной карты, например source-map-visualization или Source Map Visualization .
Сгенерированный столбец слева показывает сжатое содержимое, а исходный столбец показывает исходный источник.
Визуализатор окрашивает каждую строку исходного столбца в соответствующий код в сгенерированном столбце.
В разделе сопоставлений показаны декодированные сопоставления кода. Например, запись 65 -> 2:2
означает:
- Сгенерированный код: слово
const
начинается с позиции 65 в сжатом содержимом. - Исходный код: слово
const
начинается со второй строки и второго столбца исходного содержимого.
Это позволяет разработчикам быстро определить взаимосвязь между минимизированным и исходным кодом, что упрощает процесс отладки.
Инструменты разработчика браузера применяют эти карты исходного кода, чтобы помочь вам быстро выявить проблемы отладки в браузере.
Расширения исходной карты
Исходные карты поддерживают пользовательские поля расширения, начинающиеся с префикса x_
. Одним из примеров является поле расширения x_google_ignoreList
, предложенное Chrome DevTools. См. x_google_ignoreList, чтобы узнать больше о том, как эти расширения помогают вам сосредоточиться на своем коде.
Недостатки исходной карты
К сожалению, сопоставления источников не всегда настолько полны, насколько вам нужно. В нашем первом примере переменная greet
была оптимизирована в процессе сборки, хотя ее значение непосредственно встроено в окончательный вывод строки.
В этом случае при отладке кода инструменты разработчика могут не получить возможность вывести и отобразить фактическое значение. Подобные ошибки могут усложнить мониторинг и анализ кода.
Эту проблему необходимо решить при разработке исходных карт. Одним из возможных решений является включение информации об области действия в карты исходного кода так же, как другие языки программирования поступают со своей отладочной информацией.
Однако это требует совместной работы всей экосистемы над улучшением спецификации и реализации исходной карты. Чтобы следить за тем, как улучшаются возможности отладки с помощью исходных карт, обратитесь к предложению по исходным картам v4 на GitHub.