改善偵錯體驗
過去幾個月來,Chrome 開發人員工具團隊與 Angular 團隊合作,推出改善 Chrome 開發人員工具的偵錯體驗。這兩個團隊的成員都攜手合作,讓開發人員從編寫的角度對網頁應用程式偵錯及剖析:以來源語言和專案結構來說,使用者可以存取他們熟悉且感興趣的資訊。
這篇文章會詳細介紹 Angular 和 Chrome 開發人員工具中的哪些變更才能完成。雖然其中部分變更可以透過 Angular 呈現,但也可以套用至其他架構。Chrome 開發人員工具團隊鼓勵其他架構採用新版控制台 API 和來源對應擴充功能點,為使用者提供更優質的偵錯體驗。
忽略清單程式碼
使用 Chrome 開發人員工具對應用程式進行偵錯時,作者通常只想查看「其程式碼」,而不是查看下方架構的架構,或部分依附元件未出現在 node_modules
資料夾中。
為此,開發人員工具團隊推出來源對應的擴充功能 (名為 x_google_ignoreList
)。這個擴充功能可用來識別第三方來源,例如架構程式碼或套裝組合產生的程式碼。架構使用這項擴充功能時,作者現在會自動避免不想查看或逐步執行的程式碼,不必事先手動設定。
在實際操作時,Chrome 開發人員工具會自動隱藏堆疊追蹤、「來源」樹狀結構和「快速開啟」對話方塊中辨識的程式碼,同時改善偵錯工具的步行和繼續行為。
x_google_ignoreList
來源對應擴充功能
在來源對應中,新的 x_google_ignoreList
欄位會參照 sources
陣列,並會列出該來源對應中所有已知第三方來源的索引。剖析來源對應時,Chrome 開發人員工具會據此判斷應忽略程式碼的哪些區段。
以下是產生的檔案 out.js
的來源對應。產生輸出檔案時使用的兩個原始 sources
:foo.js
和 lib.js
。前者是網站程式開發人員編寫的內容,後者則是他們所使用的架構。
{
"version" : 3,
"file": "out.js",
"sourceRoot": "",
"sources": ["foo.js", "lib.js"],
"sourcesContent": ["...", "..."],
"names": ["src", "maps", "are", "fun"],
"mappings": "A,AAAB;;ABCDE;"
}
以下原始來源均包含 sourcesContent
,Chrome 開發人員工具則預設會在 Debugger 中顯示這些檔案:
- 「來源」樹狀結構中的檔案。
- 系統會顯示「快速開啟」對話方塊。
- 在中斷點和踏步時暫停時,錯誤堆疊追蹤中對應的呼叫框架位置。
現在您還可以在來源對應中加入一項額外資訊,以找出這些來源是第一個或第三方程式碼:
{
...
"sources": ["foo.js", "lib.js"],
"x_google_ignoreList": [1],
...
}
新的 x_google_ignoreList
欄位包含一個參照 sources
陣列的索引:1。這會指定對應至 lib.js
的區域確實是第三方程式碼,應自動新增至忽略清單。
如下方範例所示,索引 2、4 和 5 指定對應至 lib1.ts
、lib2.coffee
和 hmr.js
的區域,都是應自動新增至忽略清單的第三方程式碼。
{
...
"sources": ["foo.html", "bar.css", "lib1.ts", "baz.js", "lib2.coffee", "hmr.js"],
"x_google_ignoreList": [2, 4, 5],
...
}
如果你是架構或套裝組合開發人員,請務必在建構過程中產生的來源對應包含這個欄位,以使用 Chrome 開發人員工具中的這些新功能。
Angular 的 x_google_ignoreList
自 Angular v14.1.0 起,node_modules
和 webpack
資料夾的內容已標示為「可忽略」。
方法是建立可掛鉤至 webpack Compiler
模組的外掛程式,藉此達成 angular-cli
的變動。
我們的工程師建立的 webpack 外掛程式是建立掛鉤至 PROCESS_ASSETS_STAGE_DEV_TOOLING
階段,並在 Webpack 產生以及瀏覽器載入的最終資產來源對應中,填入 x_google_ignoreList
欄位。
const map = JSON.parse(mapContent) as SourceMap;
const ignoreList = [];
for (const [index, path] of map.sources.entries()) {
if (path.includes('/node_modules/') || path.startsWith('webpack/')) {
ignoreList.push(index);
}
}
map[`x_google_ignoreList`] = ignoreList;
compilation.updateAsset(name, new RawSource(JSON.stringify(map)));
連結的堆疊追蹤
堆疊追蹤可解答「我怎麼到這裡」的問題,但這通常是從機器的角度出發,不一定符合開發人員對應用程式執行階段的想法或心態模型。當某些作業安排稍後以非同步的方式進行時,這一點尤其重要。雖然知道這些作業的「根本原因」或排程端還是很有意思,但這項功能並不會包含在非同步堆疊追蹤中。
使用標準瀏覽器排程基本功能時,V8 內部有一套機制可以追蹤這類非同步工作,例如 setTimeout
。系統預設會完成這些操作,因此開發人員可以自行檢查!但在更複雜的專案中,這並不是那麼簡單,尤其在使用具備進階排程機制的架構時更是如此,例如用於執行區域追蹤、自訂工作佇列,或將更新分割成數個隨著時間執行的多個工作單元。
為解決這個問題,開發人員工具會在 console
物件上公開名為「Async Stack Tagging API」的機制,讓架構開發人員提示作業的排定位置和執行作業的位置。
非同步堆疊標記 API
如未設定非同步堆疊標記,針對依架構以複雜方式非同步執行的程式碼堆疊追蹤,將無法顯示與排定程式碼的程式碼連結。
使用非同步堆疊標記即可提供背景資訊,堆疊追蹤如下所示:
為此,請使用 Async Stack Tagging API 提供且名為 console.createTask()
的新 console
方法。其簽名如下所示:
interface Console {
createTask(name: string): Task;
}
interface Task {
run<T>(f: () => T): T;
}
叫用 console.createTask()
會傳回 Task
例項,您稍後可以用來執行非同步程式碼。
// Task Creation
const task = console.createTask(name);
// Task Execution
task.run(f);
此外,非同步作業也可以建立巢狀結構,而「根本原因」會依序顯示在堆疊追蹤中。
工作可執行無數次,每次執行的工作酬載可能有所不同。系統會記住排程網站的呼叫堆疊,直到收集工作物件為垃圾收集為止。
Angular 中的 Async Stack Tagging API
在 Angular 中,對 NgZone 所做的變更經過變更 – Angular 的執行環境,會在非同步工作中保留。
排程工作時,工作會使用 console.createTask()
(如果可用)。系統會儲存產生的 Task
例項,以供日後使用。叫用工作後,NgZone 會使用已儲存的 Task
執行個體執行該工作。
這些變更透過 #46693 和 #46958 提取要求,導入 Angular 的 NgZone 0.11.8。
友善的來電框
在建立專案時,架構通常會根據各種範本語言產生程式碼,例如 Angular 或 JSX 範本,這類範本會將 HTML 樣式程式碼轉成純文字,最後在瀏覽器中執行。有時候,這類產生的函式會有名稱不易使用的名稱,例如經過壓縮後輸入單一字母名稱,或是模糊不清或陌生的名稱,即使名稱並非如此。
在 Angular 中,經常會在堆疊追蹤中看到名稱為 AppComponent_Template_app_button_handleClick_1_listener
的呼叫影格。
為解決這個問題,Chrome 開發人員工具現已支援透過來源對應重新命名這些函式。如果來源對應有函式範圍開始的名稱項目 (也就是參數清單的左括號),呼叫頁框應在堆疊追蹤中顯示該名稱。
Angular 的友善呼叫框
將 Angular 中的呼叫框重新命名需要持續進行。我們預期這些改善措施會逐漸推行。
剖析作者編寫的 HTML 範本時,Angular 編譯器會產生 TypeScript 程式碼,最終會轉譯為瀏覽器載入並執行的 JavaScript 程式碼。
在這個程式碼產生過程中,系統也會建立來源對應。我們正在研究如何把函式名稱加入來源對應的「名稱」欄位,並在產生的程式碼和原始程式碼之間的對應中參照這些名稱。
舉例來說,如果事件接聽程式已產生一個函式,且其名稱在壓縮期間不易辨識或移除,現在來源對應可以在「names」欄位中加入這個函式更易記的名稱,而函式範圍開頭的對應現在可參照這個名稱 (也就是參數清單的左括號)。Chrome 開發人員工具會使用這些名稱來重新命名堆疊追蹤中的呼叫頁框。
展望未來
使用 Angular 做為測試前測計畫,確認我們所做的成果很滿意。我們很樂意聆聽架構開發人員的想法,並針對這些延長使用期限提供意見。
還有更多值得我們探索的地方。特別是如何改善開發人員工具中的剖析體驗。