簡介
如今,作者可以利用許多抽象化來建立自己的網頁應用程式。許多作者沒有直接與 Web Platform 提供的低階 API 互動,而是運用架構、建構工具和編譯器從更高層次的角度編寫應用程式。
舉例來說,以 Angular 架構為基礎打造的元件是使用 HTML 範本的 TypeScript 編寫。實際上,Angular CLI 和 Webpack 會將所有內容編譯為 JavaScript,並放入所謂的「軟體包」,然後傳送到瀏覽器。
在開發人員工具中對網頁應用程式偵錯或剖析時,您目前可以看到並偵錯這個編譯的程式碼,而非您實際編寫的程式碼。身為作者,這不是你想要的樣子,不過:
- 您不想對壓縮的 JavaScript 程式碼進行偵錯,但不想對原始的 JavaScript 程式碼進行偵錯。
- 使用 TypeScript 時,您不想對 JavaScript 進行偵錯,建議您對原始 TypeScript 程式碼進行偵錯。
- 當您像 Angular、Lit 或 JSX 一樣使用範本時,您不一定會想對產生的 DOM 進行偵錯。您可能會想要自行偵錯元件。
整體而言,您可能會在編寫自己的程式碼時對自己的程式碼進行偵錯。
雖然來源對應已經可以彌補這個落差,但 Chrome 開發人員工具和生態系統可以達成這個目標。
現在就來看看兩者的不同之處!
已編寫與已部署的程式碼
目前,在「來源面板」中瀏覽檔案樹狀結構時,可以看到經過編譯 (且通常壓縮) 的內容。這些是瀏覽器實際下載並執行的檔案。開發人員工具將其稱為已部署的程式碼。
這並不實用,而且往往很難掌握。身為作者,您想要查看並偵錯您編寫的程式碼,而非已部署的程式碼。
如要理解這部分,可以改為在樹狀結構中顯示「Authored Code」。如此一來,樹狀結構就會與您在 IDE 中看到的來源檔案更為類似,而這些檔案現在與已部署的程式碼分隔開來。
如要在 Chrome 開發人員工具中啟用這個選項,請依序前往「設定」>實驗並勾選「將來源分成已編寫和已部署的樹狀結構」。
「只要我的程式碼」
使用依附元件或以架構為基礎進行建構時,第三方檔案便可給您。在多數情況下,您只想查看程式碼,而不是有些第三方程式庫隱藏在 node_modules
資料夾中。
為解決這個問題,開發人員工具會預設啟用一項額外設定:「自動將已知的第三方指令碼新增至忽略清單」。前往「開發人員工具」DevTools>「設定」>忽略清單:
啟用這項設定後,開發人員工具會隱藏架構或建構工具標示為「設為忽略」的任何檔案或資料夾。
自 Angular v14.1.0 起,其 node_modules
和 webpack
資料夾的內容已標示為如此。因此,這些資料夾、當中的檔案和其他這類第三方成果不會顯示在開發人員工具中的多個位置。
作者不需要採取任何行動,即可啟用這項新行為,導入這項變更取決於架構。
堆疊追蹤中已忽略的程式碼
這些忽略清單檔案不再顯示於其中一處,就是堆疊追蹤。身為作者,您現在可以看到更多相關的堆疊追蹤。
如要查看堆疊追蹤的所有呼叫框架,您隨時可以按一下「Show more frames」(顯示更多頁框) 連結。
同樣的原則也適用於您在偵錯及逐步執行程式碼時看到的呼叫堆疊。當架構或軟體包商向開發人員工具通知第三方指令碼時,開發人員工具就會自動隱藏所有不相關的呼叫框架,並在執行步驟偵錯時跳出任何不相關的呼叫框架。
檔案樹狀結構中已忽略的程式碼
如要在「來源」面板的「已編寫程式碼」檔案樹狀結構中隱藏忽略清單中的檔案和資料夾,請依序前往「設定」>「隱藏來源樹狀檢視中已列入忽略的程式碼」開發人員工具中的實驗。
在 Angular 專案中,node_modules
和 webpack
資料夾現已隱藏。
「快速開啟」選單中已忽略的程式碼
忽略的項目不僅會從檔案樹狀結構中隱藏,還會從「快速開啟」選單 (Control + P (Linux/Windows) 或 Command + P (Mac)) 隱藏。
改善堆疊追蹤
在已探討相關堆疊追蹤之後,Chrome 開發人員工具會針對堆疊追蹤做出進一步改善。
連結的堆疊追蹤
當某些作業排定非同步進行時,開發人員工具中的堆疊追蹤目前只會呈現故事的一部分。
舉例來說,在假想的 framework.js
檔案中,有一個非常簡單的排程器:
function makeScheduler() {
const tasks = [];
return {
schedule(f) {
tasks.push({ f });
},
work() {
while (tasks.length) {
const { f } = tasks.shift();
f();
}
},
};
}
const scheduler = makeScheduler();
function loop() {
scheduler.work();
requestAnimationFrame(loop);
};
loop();
...以及開發人員在 example.js
檔案中的個人程式碼用途:
function someTask() {
console.trace("done!");
}
function businessLogic() {
scheduler.schedule(someTask);
}
businessLogic();
在 someTask
方法中新增中斷點或檢查控制台中顯示的追蹤記錄時,您不會看到任何提及是該作業「根本原因」的 businessLogic()
呼叫。
而是只會看到促成工作執行的架構排程邏輯,而堆疊追蹤中沒有導覽標記,這有助於找出導致這項工作之間的因果關係。
利用「非同步堆疊標記」這項新功能,您可以將非同步程式碼的兩個部分連結在一起,讓所有者述說完整的故事。
非同步堆疊標記 API 導入了名為 console.createTask()
的新 console
方法。API 簽名如下所示:
interface Console {
createTask(name: string): Task;
}
interface Task {
run<T>(f: () => T): T;
}
console.createTask()
呼叫會傳回 Task
例項,您稍後可以用來執行工作的內容 f
。
// Task Creation
const task = console.createTask(name);
// Task Execution
task.run(f);
該工作會建立起層所在的結構定義與執行的非同步函式內容之間的連結。
從上述套用至 makeScheduler
函式的程式碼,會變成下列程式碼:
function makeScheduler() {
const tasks = [];
return {
schedule(f) {
const task = console.createTask(f.name);
tasks.push({ task, f });
},
work() {
while (tasks.length) {
const { task, f } = tasks.shift();
task.run(f); // instead of f();
}
},
};
}
因此,Chrome 開發人員工具已可顯示更優質的堆疊追蹤。
請注意 businessLogic()
現已納入堆疊追蹤!不僅如此,工作會使用熟悉的名稱 someTask
,而非像之前的一般 requestAnimationFrame
。
友善的來電框
在建立專案時,架構通常會根據各種範本語言產生程式碼,例如 Angular 或 JSX 範本,這類範本會將 HTML 樣式程式碼轉成純文字,最後在瀏覽器中執行。有時候,這類產生的函式會有名稱不易使用的名稱,例如經過壓縮後輸入單一字母名稱,或是模糊不清或陌生的名稱,即使名稱並非如此。
在本例中,專案範例就是堆疊追蹤中顯示的 AppComponent_Template_app_button_handleClick_1_listener
。
為解決這個問題,Chrome 開發人員工具現已支援透過來源對應重新命名這些函式。如果來源對應含有函式範圍開始的名稱項目,呼叫框架應在堆疊追蹤中顯示該名稱。
作者不需要採取任何行動,即可啟用這項新行為,導入這項變更取決於架構。
展望未來
多虧了本文所述的資訊,Chrome 開發人員工具才能提供更優質的偵錯體驗。團隊仍希望探索更多領域。特別是如何改善開發人員工具中的剖析體驗。
Chrome 開發人員工具團隊鼓勵架構作者採用這些新功能。如要瞭解如何實作這項功能,請參閱「個案研究:使用開發人員工具改善 Angular 偵錯。