Что такое исходные карты?

Карты исходного кода — важнейший инструмент современной веб-разработки, который значительно упрощает отладку. На этой странице рассматриваются основы карт исходного кода, способы их создания и улучшения возможностей отладки.

Необходимость исходных карт

Ранние веб-приложения создавались с низкой сложностью. Разработчики разместили файлы HTML, CSS и JavaScript непосредственно в Интернете.

Более современным и сложным веб-приложениям в рабочем процессе разработки могут потребоваться различные инструменты. Например:

Краткий обзор различных инструментов.
Некоторые из распространенных инструментов разработки веб-приложений.

Этим инструментам требуется процесс сборки для преобразования вашего кода в стандартные 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 начинается со второй строки и второго столбца исходного содержимого.
Картографическая запись.
Визуализация сопоставления с акцентом на запись 65 -> 2:2 .

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

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

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

Расширения исходной карты

Исходные карты поддерживают пользовательские поля расширения, начинающиеся с префикса x_ . Одним из примеров является поле расширения x_google_ignoreList предложенное Chrome DevTools. См . x_google_ignoreList , чтобы узнать больше о том, как эти расширения помогают вам сосредоточиться на своем коде.

Недостатки исходной карты

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

Переменная приветствие не отображается.
Переменная greet в исходном коде отсутствует в сопоставлении.

В этом случае при отладке кода инструменты разработчика могут не получить возможность вывести и отобразить фактическое значение. Подобные ошибки могут усложнить мониторинг и анализ кода.

Переменная приветствие не определена.
Инструмент разработчика не может найти значение greet .

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

Однако это требует совместной работы всей экосистемы над улучшением спецификации и реализации исходной карты. Чтобы следить за тем, как улучшаются возможности отладки с помощью исходных карт, обратитесь к предложению по исходным картам v4 на GitHub.