Co to są mapy źródeł?

Ulepsz debugowanie stron internetowych dzięki mapom źródeł.

Dziś mówimy o mapach źródłowych – kluczowym narzędziu dla współczesnego tworzenia stron internetowych, które znacznie ułatwia debugowanie. Z tego artykułu dowiesz się, jak działają mapy źródeł, jak są generowane i jak zwiększają one możliwości debugowania.

Potrzeba map źródeł

W dawnych, dobrych czasach tworzyliśmy aplikacje internetowe oparte wyłącznie na HTML, CSS i JavaScript, a następnie wdrażaliśmy te same pliki w sieci.

Ponieważ jednak tworzymy obecnie bardziej złożone aplikacje internetowe, Twój przepływ pracy może wymagać korzystania z różnych narzędzi. Na przykład:

Krótkie omówienie różnych narzędzi.

Narzędzia te wymagają procesu kompilacji w celu transpilacji kodu do standardowego kodu HTML, JavaScript i CSS, który jest zrozumiały dla przeglądarek. W celu optymalizacji wydajności często jest też kompresowana (np. za pomocą skryptu Terser służąca do minifikacji i przekształcania kodu JavaScript) oraz łączenie tych plików, zmniejszając ich rozmiar i zwiększając wydajność w internecie.

Na przykład za pomocą narzędzi do tworzenia możemy przetranspilować i skompresować następujący plik TypeScript do jednego wiersza kodu JavaScript. Możesz zagrać w tę wersję demonstracyjną w moim repozytorium na GitHubie.

/* 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);
});

Wersja skompresowana to:

/* 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)}));

Taka optymalizacja może jednak utrudnić debugowanie. Skompresowany kod zawierający wszystko w jednym wierszu i krótsze nazwy zmiennych mogą utrudniać zlokalizowanie źródła problemu. Właśnie tu do akcji wkraczają mapy źródłowe – mapują skompilowany kod z powrotem na oryginalny kod.

Generuję mapy źródeł

Mapy źródłowe to pliki o nazwach kończących się znakami .map (np. example.min.js.map i styles.css.map). Można je generować za pomocą większości narzędzi do kompilacji, takich jak Vite, pakiet internetowy, Rollup, Parcel czy esbuild.

Niektóre narzędzia zawierają domyślnie mapy źródeł, a inne mogą wymagać dodatkowej konfiguracji do ich wygenerowania.

/* 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
  }
})

Informacje o mapie źródeł

Pliki map źródłowych zawierają kluczowe informacje o tym, jak skompilowany kod jest mapowany na oryginalny kod, co ułatwia programistom debugowanie. Oto przykład mapy źródeł.

{
  "mappings": "AAAAA,SAASC,cAAc,WAAWC, ...",
  "sources": ["src/script.ts"],
  "sourcesContent": ["document.querySelector('button')..."],
  "names": ["document","querySelector", ...],
  "version": 3,
  "file": "example.min.js.map"
}

Aby zapoznać się z każdym z tych pól, możesz przeczytać specyfikację mapy źródłowej lub ten klasyczny artykuł na temat budowy mapy źródeł.

Najważniejszym aspektem mapy źródłowej jest pole mappings. Używa ciągu zakodowanego w standardzie VLQ zakodowanym w standardzie 64 do mapowania wierszy i lokalizacji ze skompilowanego pliku na odpowiedni oryginalny plik. Mapowanie to można zwizualizować za pomocą wizualizacji mapy źródłowej, takiej jak source-map-Visualization czy Wizualizacja mapy źródeł.

Wizualizacja mapy źródeł.
Obraz przedstawia wizualizację poprzedniego przykładowego kodu powyżej wygenerowaną przez wizualizację.

Kolumna wygenerowane po lewej stronie pokazuje skompresowaną treść, a kolumna oryginalna – oryginalne źródło.

Wizualizacja koduje poszczególne wiersze w kolumnie original (oryginał) i odpowiadający im kod w kolumnie generated (wygenerowane).

Sekcja mappings przedstawia zdekodowane mapowania kodu. Na przykład wpis 65-> 2:2 oznacza:

  • Wygenerowany kod: słowo const zaczyna się na pozycji 65 w skompresowanej treści.
  • Kod oryginalny: słowo const zaczyna się w wierszu 2 i kolumnie 2 w oryginalnej treści.

Wpis mapowania.

Dzięki temu deweloperzy mogą szybko zidentyfikować relację między zminimalizowanym a oryginalnym kodem, co usprawnia debugowanie.

Narzędzia dla programistów w przeglądarce stosują te mapy źródeł, aby pomóc Ci szybciej wyłapać problemy z debugowaniem bezpośrednio w przeglądarce.

Narzędzia dla programistów stosują mapę źródeł.

Obraz pokazujący, jak Narzędzia dla programistów w przeglądarce stosują mapy źródeł i pokazują mapowania między plikami.

Rozszerzenia mapy źródeł

Rozszerzenia pomocy map źródeł. Rozszerzenia to pola niestandardowe, których nazwa zaczyna się od konwencji nazewnictwa x_. Jednym z przykładów jest pole rozszerzenia x_google_ignoreList proponowane przez Narzędzia deweloperskie w Chrome. Więcej informacji o tym, jak te rozszerzenia pomogą Ci skupić się na kodzie, znajdziesz w zapisie x_google_ignoreList.

Nie jest doskonała

W naszym przykładzie zmienna greet została zoptymalizowana podczas procesu kompilacji. Wartość została umieszczona bezpośrednio w wyniku końcowego ciągu znaków.

Powitanie Variaqble nie jest mapą.

W takim przypadku podczas debugowania kodu narzędzia dla programistów mogą nie być w stanie wywnioskować i wyświetlić rzeczywistej wartości. To nie jest tylko wyzwanie dla narzędzi dla programistów w przeglądarce. Utrudnia to też monitorowanie i analizę kodu.

Powitanie zmiennej jest nieokreślone.

Ten problem można oczywiście rozwiązać. Jednym ze sposobów jest uwzględnienie informacji o zakresie w mapach źródłowych, tak jak w przypadku innych języków programowania.

Wymaga to jednak współpracy całego ekosystemu w celu ulepszenia specyfikacji map źródłowych i ich implementacji. Toczy się aktywna dyskusja na temat zwiększania możliwości debugowania za pomocą map źródeł.

Zamierzamy ulepszyć mapy źródeł i sprawić, że debugowanie będzie jeszcze łatwiejsze.