Co to są mapy źródeł?

Mapy źródeł są kluczowym narzędziem w nowoczesnym tworzeniu stron internetowych, które znacznie ułatwiają debugowanie. Na tej stronie poznasz podstawy map źródeł, dowiesz się, jak są one generowane i jak poprawiają one działanie debugowania.

Potrzeba map źródeł

Pierwsze aplikacje internetowe były tworzone o niewielkiej złożoności. Programiści wdrażali pliki HTML, CSS i JavaScript bezpośrednio w internecie.

Bardziej nowoczesne i złożone aplikacje internetowe mogą wymagać różnych narzędzi w procesie programowania. Na przykład:

Krótkie omówienie różnych narzędzi.
Niektóre z popularnych narzędzi do tworzenia aplikacji internetowych.

Narzędzia te wymagają procesu kompilacji w celu transpilacji kodu do standardowego, zrozumiałego dla przeglądarki kodu HTML, JavaScript i CSS. Popularną praktyką jest też optymalizacja wydajności przez minifikowanie i łączenie tych plików za pomocą takiego narzędzia jak Terser.

Na przykład za pomocą narzędzi do kompilacji możemy przetranspilować i skompresować poniższy plik TypeScript i umieścić go w jednym wierszu kodu JavaScript. Możesz ją wypróbować w tej prezentacji w 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)}));

Kompresja kodu może jednak utrudniać debugowanie. Mapy źródeł mogą wyeliminować ten problem: mapując skompilowany kod z powrotem na pierwotny kod, można szybko znaleźć źródło błędu.

Wygeneruj mapy źródeł

Mapy źródłowe to pliki, których nazwy kończą się na .map (np. example.min.js.map i styles.css.map). Można je generować przez większość narzędzi do kompilacji, w tym Vite, pakiet internetowy, Rollup, Parcel i kompilacje.

Niektóre narzędzia domyślnie zawierają mapy źródeł. Inne mogą wymagać dodatkowej konfiguracji,

/* 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ł

Aby ułatwić debugowanie, pliki map źródłowych zawierają istotne informacje o tym, jak skompilowany kod jest mapowany na oryginalny kod. Oto przykład mapy źródłowej:

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

Aby zrozumieć każde z tych pól, możesz przeczytać specyfikację mapy źródłowej lub Anatomię mapy źródeł.

Najważniejszą częścią mapy źródłowej jest pole mappings. Używa ciągu zakodowanego w standardzie VLQ w standardzie 64 do mapowania wierszy i lokalizacji ze skompilowanego pliku na odpowiedni plik oryginalny. Mapowanie możesz wyświetlić za pomocą wizualizacji mapy źródeł, takiej jak source-map-Visualization lub Wizualizacja mapy źródeł.

Wizualizacja mapy źródeł.
Wizualizacja poprzedniego przykładowego kodu wygenerowana przez wizualizatora.

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

Wizualizacja oznacza kolorami każdy wiersz w kolumnie original (oryginał) odpowiednim kodem w kolumnie Generate (wygenerowany).

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.
Wizualizacja mapowania, skupiona na pozycji 65 -> 2:2.

Pozwala to programistom szybko zidentyfikować relację między zminimalizowanym a oryginalnym kodem, co usprawnia debugowanie.

Narzędzia deweloperskie w przeglądarce stosują te mapy źródeł, aby ułatwić Ci szybkie identyfikowanie problemów z debugowaniem.

Narzędzia dla programistów stosujące mapę źródeł.
Przykład sposobu, w jaki narzędzia dla programistów w przeglądarce stosują mapy źródeł i pokazują mapowania między plikami.

Rozszerzenia mapy źródeł

Mapy źródeł obsługują pola rozszerzeń niestandardowych, które zaczynają się prefiksem 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 pomagają Ci skupić się na kodzie, znajdziesz w sekcji x_google_ignoreList.

Wady mapy źródłowej

Niestety mapowania źródeł nie zawsze są tak kompletne, jak potrzebujesz. W pierwszym przykładzie zmienna greet została zoptymalizowana podczas procesu kompilacji, mimo że jej wartość jest bezpośrednio umieszczona w danych wyjściowych ciągu końcowego.

Zmienna powitanie nie jest zmapowana.
W mapowaniu brakuje zmiennej greet w pierwotnym kodzie.

W takim przypadku podczas debugowania kodu narzędzia dla programistów mogą nie być w stanie wywnioskować ani wyświetlić rzeczywistej wartości. Taki błąd może utrudnić monitorowanie i analizę kodu.

Powitanie zmiennej jest nieokreślone.
Narzędzie dla deweloperów nie może znaleźć wartości parametru greet.

Jest to problem, który trzeba rozwiązać w ramach projektu map źródeł. Jednym z potencjalnych rozwiązań jest uwzględnienie informacji o zakresie w mapach źródłowych w taki sam sposób jak dane debugowania w innych językach programowania.

Wymaga to jednak współpracy całego ekosystemu w celu ulepszenia specyfikacji mapy źródłowej i jej wdrożenia. Aby kontynuować ulepszanie możliwości debugowania za pomocą map źródeł, zapoznaj się z propozycją dotyczącą Map źródłowych w wersji 4 na GitHubie.