改善偵錯體驗
在過去幾個月,Chrome 開發人員工具團隊與 Angular 團隊合作,推出 Chrome 開發人員工具中偵錯體驗的改善功能。兩個團隊的人員合作無間,並採取措施,讓開發人員能從編寫角度對網頁應用程式進行偵錯和分析,並存取與其相關的熟悉資訊。
本文將深入探討 Angular 和 Chrome 開發人員工具中,哪些變更可達成這項目標。雖然這些變更有些是透過 Angular 示範,但也可以套用至其他架構。Chrome 開發人員工具團隊鼓勵其他架構採用新的控制台 API 和原始碼對應擴充點,以便為使用者提供更優質的偵錯體驗。
忽略清單程式碼
使用 Chrome 開發人員工具偵錯應用程式時,作者通常只想查看自己的程式碼,而不是底層架構或 node_modules
資料夾中隱藏的某些依附元件。
為達成這項目標,開發人員工具團隊已為來源對應引進擴充功能,稱為 x_google_ignoreList
。這個擴充功能可用於識別第三方來源,例如架構程式碼或 Bundler 產生的程式碼。當架構使用這個擴充功能時,作者現在可以自動避開不想查看或逐步查看的程式碼,而無須事先手動設定。
實際上,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 開發人員工具會根據預設在偵錯工具中顯示這些檔案:
- 做為來源資料樹狀結構中的檔案。
- 顯示在「快速開啟」對話方塊中的結果。
- 在暫停在中斷點和執行步驟時,在錯誤堆疊追蹤中顯示對應的呼叫框架位置。
您現在可以將另一項資訊加入來源對應圖,以便識別哪些來源是第一方或第三方程式碼:
{
...
"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 14.1.0 版起,node_modules
和 webpack
資料夾的內容已標示為「要忽略」。
這項變更是透過變更 angular-cli
而達成,方法是建立可鉤進 webpack 的 Compiler
模組的外掛程式
我們的工程師建立的 webpack 外掛程式會將鉤子加入 PROCESS_ASSETS_STAGE_DEV_TOOLING
階段,並在來源對應中填入 x_google_ignoreList
欄位,以便 webpack 產生最終資產並供瀏覽器載入。
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)));
已連結的堆疊追蹤
堆疊追蹤可回答「我如何來到這裡」的問題,但這通常是從機器的角度來看,不一定符合開發人員的觀點或他們對應用程式執行階段的心理模型。當某些作業排定在稍後以非同步方式執行時,這一點尤其適用:雖然瞭解這類作業的「根本原因」或排程方面仍可能很有幫助,但這類資訊並不會是非同步堆疊追蹤的一部分。
在使用標準瀏覽器排程原語 (例如 setTimeout
) 時,V8 內部會提供機制,用於追蹤這類非同步工作。在這些情況下,系統會預設執行這項操作,因此開發人員可以檢查這些項目。但在較複雜的專案中,情況就沒那麼簡單,尤其是在使用具備更進階排程機制的架構時,例如執行區域追蹤、自訂工作佇列,或將更新分割成多個工作單元,並在一段時間內執行。
為解決這個問題,DevTools 會在 console
物件上公開稱為「非同步堆疊標記 API」的機制,讓架構開發人員可以同時提示作業的排程位置和執行位置。
Async Stack Tagging 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()
,系統就會使用 console.createTask()
。系統會儲存產生的 Task
例項,以供日後使用。在叫用工作時,NgZone 會使用儲存的 Task
例項來執行工作。
這些變更已透過提取要求 #46693 和 #46958 納入 Angular 的 NgZone 0.11.8 版。
友善呼叫框
建構專案時,架構通常會從各種範本語言產生程式碼,例如 Angular 或 JSX 範本,可將看起來像 HTML 的程式碼轉換為純 JavaScript,最終在瀏覽器中執行。有時,這類產生的函式會以不太友善的名稱命名,例如經過精簡後的單字母名稱,或是不太友善或不熟悉的名稱。
在 Angular 中,在堆疊追蹤中看到名稱為 AppComponent_Template_app_button_handleClick_1_listener
的呼叫框架並不罕見。
為解決這個問題,Chrome 開發人員工具現在支援透過原始碼對照圖重新命名這些函式。如果原始碼對應圖包含函式範圍開頭的名稱項目 (也就是參數清單的左括號),呼叫框架應會在堆疊追蹤中顯示該名稱。
Angular 中的友善呼叫框
我們會持續努力在 Angular 中重新命名呼叫框架。我們預計這些改善項目會逐步推出。
在剖析作者編寫的 HTML 範本時,Angular 編譯器會產生 TypeScript 程式碼,並最終轉譯為瀏覽器載入及執行的 JavaScript 程式碼。
在這個程式碼產生程序中,也會建立原始碼對照表。我們目前正在研究如何在原始對照圖的「名稱」欄位中加入函式名稱,並在產生的程式碼和原始程式碼之間的對應項目中參照這些名稱。
舉例來說,如果事件事件監聽器的函式產生,但名稱不友善或在縮減期間遭到移除,現在來源對應圖可在「names」欄位中加入這個函式的友善名稱,而函式範圍開頭的對應項目現在可參照這個名稱 (也就是參數清單的左括號)。接著,Chrome 開發人員工具會使用這些名稱,重新命名堆疊追蹤中的呼叫頁框。
展望未來
使用 Angular 做為測試前景,驗證我們的成果,是相當棒的體驗。我們非常歡迎架構開發人員提供意見,並針對這些擴充點提供意見回饋。
我們還想探索更多領域。特別是如何改善開發人員工具中的分析體驗。