iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 10
2
Modern Web

你所不知道的各種前端 Debug 技巧系列 第 10

[Day 10] Sources - Source Map & File Editing

終於來到了重頭戲 Sources 面板,前面的文章提到了許多提高 Debug 效率的小撇步,但如果遇到了更加複雜的情境,透過 Console、Elements 面板都無法解決,此時就是 Sources 面板的出場時機。

閱讀本篇文章時建議搭配 Demo 頁面 Sources - Source Map & File Editing,效果更佳。

概覽

打開 Sources 面板後可以看到主要分成左中右三個面板,左側面板主要和當前頁面的資源相關,在面板中會看到已載入的資源如 HTML、CSS、JS 等等檔案以資料夾的型式呈現,也可以修改、儲存檔案改變當前的頁面的行為。

右側面板為 JavaScript Debugger,上方是 Debugger 的操作按鈕以及 JavaScript 執行環境的資訊,搭配中、右側面板能夠清楚觀察 JavaScript 的執行狀況,並以斷點、逐步執行、監看狀態等功能輔助 Debug。

中間的面板主要負責顯示檔案內容,搭配左右兩側面板有不同的效果,在上方也能將兩側面板收合,可以依據自身對 Sources 面板的使用需求改變各個子面板的收合狀態和寬度。

不過在開始講解 Sources 面板的功能之前,得先介紹 Source map 和 File editing 功能是甚麼玩意兒。

Source map

現今前端開發總跟框架脫離不了關係,也讓許多網頁上執行的 JavaScript 都會預先經過處理,與開發時所看到的原始碼有所不同,常見的處理工具包括:

Compiler

如 TypeScript,將一種程式語言轉換為另一種,也可能會有效能上的優化。

Transpiler

如 Babel,將原始碼轉換為瀏覽器中可以直接使用的 JavaScript,基本上不改變程式碼的邏輯,不過隨著 Babel 的更新,也出現了 @babel/preset-typescript plugin,因此也可視為 Compiler。

Bundler

如 Webpack、Rollup,將程式碼、資源打包成網頁,可搭配 Transpiler、Loader 等等,把網頁用到的所有資源包成一個檔案。

Compressor

如 Terser,對程式碼進行 Tree shake,刪去沒用到的原始碼。

 
有了這些工具的幫忙,才能夠直接在程式碼中使用瀏覽器尚未支援的 JavaScript 語法、常用在 React 的 JSX,或是合併、壓縮程式碼來提升網頁效能等等,但經歷多道轉換的原始碼早已面目全非,遇到問題時幾乎無法用來 Debug,於是 Source map 就出現了。

原始碼 VS 打包後的程式碼

 

Why

通常在 Debug 的時候會藉由錯誤訊息、Call stack、行號等等來找出問題,但原始碼經過轉換後變數名稱、行號已經完全不同,這時就要依靠 Source map 來映射轉換前後的程式碼位置,出錯時才能對應到原始碼進行 Debug。

另外不只是 JavaScript,Source map 也能應用在其他資源如經過了 Bundler、SASS 工具轉換過的 CSS。

原理

至於程式碼的映射方式,其實就是建立一份程式碼、原始碼字元位置對照表,並把對照表的路徑放在實際執行的程式碼中來讀取,其步驟大概是:

  1. 原始碼打包成一行執行碼
  2. 將原始碼的每個變數存為陣列
  3. 將執行碼各個字元對應到原始碼的行號和陣列位置
  4. 以 VLQ 和 Base64 編碼產出最終的 Source map

注意到右下角的 source mapped from log.js 嗎?

有了對照表,當網頁中的程式碼出錯時就能映射到原始碼的位置,也就能夠從原始碼下手如新增斷點來 Debug。

考量篇幅及主題,想要深入了解對照表的產生方式請參考實作原理,真的非常有趣,值得一看,另外在實作原理文章下方可以看到 Source map 的官方規範,你沒看錯,就是一份 Google docs 文件。

 

File Editing

File Editing 是在 DevTools 中編輯頁面檔案的功能,總歸一句就是把 Chrome DevTools 當成 IDE 來使用,可以直接打開這個 Sources - Files 來試試。

進入 Demo 網頁後先開啟 DevTools,照著 Console 裡面的提示

  1. 先打開 Source 面板的 Page 頁籤
  2. 按下 index.js 開啟程式碼
  3. 編輯 index.js 的 greet function 後按 Command+S 存檔

馬上就會看到程式碼的行為改變了!基本的檔案編輯功能就這樣,非常直覺簡單,提供了一個簡易的程式碼編輯功能來改變網頁行為。

不過讀者是否有發現可以編輯 JavaScript、CSS 等檔案,但卻不能編輯 HTML,且即使按下存檔,上方會出現一個驚嘆號圖示,重整頁面後剛才的修改就全都消失了,該怎麼保留編輯的內容呢?請待下回分曉。

無法儲存到檔案系統!?

 

小結

今天提及的 Source map 在 Sources 面板扮演了非常重要的角色,常見的 Bundle tools 也都有關於 Source map 的設定(如 Webpack),能依照需求及環境決定是否建立 Source map 以及建立的方式。

另外現在 Chrome DevTools 中的 File editing 只剩下功能而沒有頁籤,取而代之的是 Filesystem 和 Overrides,會在 Sources - Workspace 中詳細介紹。


上一篇
[Day 09] Console - Run JavaScript
下一篇
[Day 11] Sources - Workspace
系列文
你所不知道的各種前端 Debug 技巧30

尚未有邦友留言

立即登入留言