Co to są mapy źródeł?

Mapy źródeł to kluczowe narzędzie w nowoczesnym tworzeniu stron internetowych, które znacznie ułatwia debugowanie. Na tej stronie znajdziesz podstawowe informacje o mapach źródeł, ich generowaniu i tym, jak ułatwiają debugowanie.

Potrzebujesz map źródłowych

Wczesne aplikacje internetowe były proste. Deweloperzy wdrożyli pliki HTML, CSS i JavaScript bezpośrednio do sieci.

Bardziej nowoczesne i złożone aplikacje internetowe mogą wymagać różnych narzędzi w ramach przepływu pracy związanego z rozwojem. Na przykład:

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

Te narzędzia wymagają procesu kompilacji, aby przetłumaczyć kod na standardowy kod HTML, JavaScript i CSS, który rozumieją przeglądarki. Popularną praktyką jest też optymalizowanie wydajności przez kompresowanie i łączenie tych plików za pomocą narzędzia takiego jak Terser.

Na przykład za pomocą narzędzi do kompilacji możemy transpilować i skompresować poniższy plik TypeScript do jednego wiersza JavaScriptu. Możesz to sprawdzić samodzielnie w wersji demonstracyjnej 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:

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

Kompresowanie kodu może jednak utrudnić debugowanie. Mapy źródeł mogą rozwiązać ten problem: dzięki zmapowaniu skompilowanego kodu na kod źródłowy mogą pomóc w szybkim znalezieniu źródła błędu.

Generowanie map źródłowych

Mapy źródeł to pliki, których nazwy kończą się na .map (np. example.min.js.mapstyles.css.map). Mogą być generowane przez większość narzędzi do kompilacji, w tym Vite, webpack, Rollup, Parcelesbuild.

Niektóre narzędzia domyślnie zawierają mapy źródłowe. Inne mogą wymagać dodatkowej konfiguracji, aby je wygenerować:

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

Te pliki mapy źródłowej zawierają istotne informacje o tym, jak skompilowany kod jest mapowany na pierwotny kod, co ułatwia 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 dowiedzieć się więcej o każdym z tych pól, przeczytaj specyfikację mapy źródeł lub artykuł Anatomia mapy źródeł.

Najważniejszym elementem mapy źródłowej jest pole mappings. Wykorzystuje ciąg zakodowany w standardzie VLQ base 64 do mapowania wierszy i lokalizacji w skompilowanym pliku na odpowiedni plik oryginalny. Możesz wyświetlić to mapowanie za pomocą wizualizacji mapy źródłowej, takiej jak source-map-visualization lub Source Map Visualization.

Wizualizacja mapy źródeł
Wizualizacja poprzedniego przykładu kodu wygenerowana przez wizualizer.

Kolumna Wygenerowana po lewej stronie pokazuje skompresowane treści, a kolumna Oryginał – oryginalne źródło.

Wizualizacja przypisuje kolor do każdego wiersza w kolumnie oryginalna, a następnie przypisuje odpowiedni kod do kolumny wygenerowana.

Sekcja mapowania zawiera odkodowane mapowania kodu. Na przykład wpis 65 -> 2:2 oznacza:

  • Wygenerowany kod: słowo const zaczyna się w pozycji 65 w skompresowanej treści.
  • Oryginalny kod: słowo const zaczyna się w 2. wierszu i 2. kolumnie oryginalnej treści.
Wpis mapowania.
Wizualizacja mapowania z powiększeniem pozycji 65 -> 2:2.

Dzięki temu deweloperzy mogą szybko zidentyfikować relację między zminifikowanym kodem a pierwotnym kodem, co ułatwia debugowanie.

Narzędzia dla programistów przeglądarek stosują te mapy źródeł, aby ułatwić Ci szybkie wykrywanie problemów związanych z debugowaniem w przeglądarce.

Narzędzia dla programistów stosujące mapę źródłową.
Przykład zastosowania przez narzędzia dewelopera przeglądarki map źródłowych i mapowania między plikami.

Rozszerzenia mapy źródłowej

Mapy źródeł obsługują niestandardowe pola rozszerzeń, które zaczynają się od prefiksu x_. Przykładem jest pole rozszerzenia x_google_ignoreList zaproponowane przez narzędzia programistyczne Chrome. Aby dowiedzieć się więcej o tym, jak te rozszerzenia pomagają Ci skupić się na kodzie, zapoznaj się z parametrem x_google_ignoreList.

Wady mapy źródłowej

Niestety mapowania źródeł nie zawsze są tak dokładne, jak byś chciał(-a). W pierwszym przykładzie zmienna greet została zoptymalizowana podczas procesu kompilacji, mimo że jej wartość jest bezpośrednio wbudowana w końcowym ciągu znaków.

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

W takim przypadku podczas debugowania kodu narzędzia dla deweloperów mogą nie być w stanie określić ani wyświetlić rzeczywistej wartości. Ten rodzaj błędu może utrudniać monitorowanie i analizowanie kodu.

Zmienna greet jest niezdefiniowana.
Narzędzie dla deweloperów nie może znaleźć wartości dla greet.

Ten problem wymaga rozwiązania w ramach projektu map źródłowych. Jednym z potencjalnych rozwiązań jest uwzględnienie informacji o zakresie w mapach źródłowych w taki sam sposób, w jaki inne języki programowania podają informacje debugowania.

Wymaga to jednak współpracy całego ekosystemu przy ulepszaniu specyfikacji i implementacji mapy źródłowej. Aby dowiedzieć się więcej o zwiększaniu możliwości debugowania za pomocą map źródłowych, zapoznaj się z propozycją Map źródłowych w wersji 4 w GitHubie.