什麼是來源對應?

運用來源地圖改善網路偵錯體驗。

今天要談談來源對應,這是現代網頁開發中扮演的重要工具,能大幅簡化偵錯作業。本文將探討來源地圖的基本概念、如何產生,以及改善偵錯體驗。

對來源對應的需求

早在不久前,我們用純粹的 HTML、CSS 和 JavaScript 建立了網頁應用程式,並將相同的檔案部署至網路。

不過,隨著我們現在要建立更複雜的網頁應用程式,您的開發工作流程可能會使用多種工具。例如:

各種工具的概要說明。

這些工具需要建構程序,才能將程式碼轉譯為瀏覽器能理解的標準 HTML、JavaScript 和 CSS。此外,為了提高效能,常見的做法是壓縮 (例如使用 Terser 來壓縮和放大 JavaScript) 並合併這些檔案,藉此縮減檔案大小,並提高網頁存取效率。

舉例來說,您可以使用建構工具將下列 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.mapstyles.css.map)。大多數建構工具 (例如 VitewebpackRollupParcelesbuild 等) 都會產生。

有些工具預設會納入來源對應,有些則可能需要額外設定才能產生。

/* 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-visualizationSource Map Visualization 等來源地圖視覺化工具,以視覺化方式呈現這項對應。

來源地圖視覺化。
上圖顯示了上個透過視覺化工具產生的程式碼範例。

左側的「產生」資料欄會顯示壓縮內容,「原始」欄則顯示原始來源。

在「原始」資料欄中,視覺化工具中的每一行顏色都會加上顏色標記,並在「generated」欄中對應其對應程式碼。

「對應」區段會顯示程式碼的解碼對應。舉例來說,65-> 2:2 項目代表:

  • 已產生的程式碼:const 字詞從壓縮內容中的位置 65 開始。
  • 原始程式碼:在原始內容中的第 2 行和第 2 欄開始輸入 const 字詞。

對應項目。

如此一來,開發人員就能快速識別壓縮後程式碼與原始程式碼之間的關係,讓偵錯作業更加順暢。

瀏覽器開發人員工具會套用這些來源對應,方便您直接在瀏覽器中找出偵錯問題。

開發人員工具會套用來源對應。

這張圖片顯示瀏覽器開發人員工具如何套用來源對應,以及檔案之間的對應關係。

來源對應擴充功能

來源對應支援擴充功能。擴充功能是開頭為 x_ 命名慣例的自訂欄位。其中一個範例就是 Chrome 開發人員工具提議的 x_google_ignoreList 擴充功能欄位。如要進一步瞭解這些擴充功能如何協助您專注在程式碼上,請參閱 x_google_ignoreList

不盡完美

在本範例中,變數 greet 已在建構程序期間最佳化。這個值會直接內嵌至最終字串輸出內容。

《Variaqble greet》不是地圖。

在這種情況下,當您對程式碼進行偵錯時,開發人員工具可能無法推論出及顯示實際值。這不僅僅是瀏覽器的開發人員工具,這也讓程式碼監控和分析工作變得更加困難。

未定義變數問候語。

這當然是一個可以解決的問題。其中一個方法是在來源對應中加入範圍資訊,就像其他程式設計語言和偵錯資訊一樣。

不過,整個生態系統必須互相搭配運作,才能改善來源對應規格和實作方式。目前有積極討論,旨在改善來源對應時的偵錯能力。

我們期望能改善來源地圖,讓偵錯變得更簡單!