Pengalaman proses debug yang ditingkatkan
Selama beberapa bulan terakhir, tim Chrome DevTools berkolaborasi dengan tim Angular untuk meluncurkan peningkatan pada pengalaman proses debug di Chrome DevTools. Orang-orang dari kedua tim tersebut bekerja sama dan mengambil langkah-langkah untuk memungkinkan developer men-debug dan membuat profil aplikasi web dari perspektif penulisan: dalam hal bahasa sumber dan struktur project, dengan akses ke informasi yang sudah dikenal dan relevan bagi mereka.
Postingan ini membahas detail untuk melihat perubahan apa saja di Angular dan Chrome DevTools yang diperlukan untuk mencapai hal ini. Meskipun beberapa perubahan ini ditunjukkan melalui Angular, perubahan tersebut juga dapat diterapkan ke framework lain. Tim Chrome DevTools mendorong framework lain untuk mengadopsi API konsol dan titik ekstensi peta sumber baru sehingga mereka juga dapat menawarkan pengalaman proses debug yang lebih baik kepada pengguna.
Kode daftar abaikan
Saat men-debug aplikasi menggunakan Chrome DevTools, penulis biasanya hanya ingin melihat kode mereka saja, bukan kode framework di bawahnya atau beberapa dependensi yang disembunyikan di folder node_modules
.
Untuk mencapai hal ini, tim DevTools telah memperkenalkan ekstensi ke peta sumber, yang disebut x_google_ignoreList
. Ekstensi ini digunakan untuk mengidentifikasi sumber pihak ketiga seperti kode framework atau kode yang dihasilkan oleh bundler. Saat framework menggunakan ekstensi ini, penulis kini secara otomatis menghindari kode yang tidak ingin mereka lihat atau lalui tanpa harus mengonfigurasinya secara manual sebelumnya.
Dalam praktiknya, Chrome DevTools dapat otomatis menyembunyikan kode yang diidentifikasi sebagai kode yang tidak digunakan lagi dalam pelacakan tumpukan, hierarki Sumber, dialog Buka Cepat, dan juga meningkatkan perilaku langkah demi langkah dan melanjutkan di debugger.
Ekstensi peta sumber x_google_ignoreList
Dalam peta sumber, kolom x_google_ignoreList
baru mengacu pada array sources
, dan mencantumkan indeks semua sumber pihak ketiga yang diketahui dalam peta sumber tersebut. Saat mengurai peta sumber, Chrome DevTools akan menggunakannya untuk mengetahui bagian kode mana yang harus ditambahkan ke daftar abaikan.
Berikut adalah peta sumber untuk file out.js
yang dihasilkan. Ada dua sources
asli yang berkontribusi dalam membuat file output: foo.js
dan lib.js
. Yang pertama adalah sesuatu yang ditulis oleh developer situs web dan yang kedua adalah framework yang mereka gunakan.
{
"version" : 3,
"file": "out.js",
"sourceRoot": "",
"sources": ["foo.js", "lib.js"],
"sourcesContent": ["...", "..."],
"names": ["src", "maps", "are", "fun"],
"mappings": "A,AAAB;;ABCDE;"
}
sourcesContent
disertakan untuk kedua sumber asli ini dan Chrome DevTools akan menampilkan file ini secara default di seluruh Debugger:
- Sebagai file dalam hierarki Sumber.
- Sebagai hasil di dialog Buka Cepat.
- Sebagai lokasi frame panggilan yang dipetakan dalam pelacakan tumpukan error saat dijeda pada titik henti sementara dan saat melakukan langkah.
Ada satu informasi tambahan yang kini dapat disertakan dalam peta sumber untuk mengidentifikasi sumber mana yang merupakan kode pihak pertama atau pihak ketiga:
{
...
"sources": ["foo.js", "lib.js"],
"x_google_ignoreList": [1],
...
}
Kolom x_google_ignoreList
baru berisi satu indeks yang merujuk ke array sources
: 1. Hal ini menentukan bahwa region yang dipetakan ke lib.js
sebenarnya adalah kode pihak ketiga yang harus otomatis ditambahkan ke daftar yang diabaikan.
Dalam contoh yang lebih kompleks, yang ditunjukkan di bawah, indeks 2, 4, dan 5 menentukan bahwa region yang dipetakan ke lib1.ts
, lib2.coffee
, dan hmr.js
adalah semua kode pihak ketiga yang harus otomatis ditambahkan ke daftar abaikan.
{
...
"sources": ["foo.html", "bar.css", "lib1.ts", "baz.js", "lib2.coffee", "hmr.js"],
"x_google_ignoreList": [2, 4, 5],
...
}
Jika Anda adalah developer framework atau paket, pastikan peta sumber yang dihasilkan selama proses build menyertakan kolom ini untuk menghubungkan ke kemampuan baru ini di Chrome DevTools.
x_google_ignoreList
di Angular
Mulai Angular v14.1.0, konten folder node_modules
dan webpack
telah ditandai sebagai “to ignore”.
Hal ini dicapai melalui perubahan pada angular-cli
dengan membuat plugin yang terhubung ke modul Compiler
webpack
Plugin webpack yang dibuat engineer kami membuat hook ke tahap PROCESS_ASSETS_STAGE_DEV_TOOLING
dan mengisi kolom x_google_ignoreList
di peta sumber untuk aset akhir yang dihasilkan webpack dan dimuat browser.
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)));
Stack trace tertaut
Stack trace menjawab pertanyaan “bagaimana saya sampai di sini”, tetapi sering kali ini berasal dari perspektif mesin, dan tidak selalu cocok dengan perspektif developer atau model mental mereka tentang runtime aplikasi. Hal ini terutama berlaku jika beberapa operasi dijadwalkan untuk terjadi secara asinkron nanti: mengetahui “penyebab utama” atau sisi penjadwalan operasi tersebut mungkin masih menarik, tetapi hal itu tidak akan menjadi bagian dari pelacakan tumpukan asinkron.
V8 secara internal memiliki mekanisme untuk melacak tugas asinkron tersebut saat primitif penjadwalan browser standar digunakan, seperti setTimeout
. Hal ini dilakukan secara default dalam kasus tersebut, sehingga developer dapat memeriksanya. Namun, dalam project yang lebih kompleks, hal ini tidak sesederhana itu, terutama saat menggunakan framework dengan mekanisme penjadwalan yang lebih canggih—misalnya, framework yang melakukan pelacakan zona, antrean tugas kustom, atau yang membagi update menjadi beberapa unit pekerjaan yang dijalankan dari waktu ke waktu.
Untuk mengatasi hal ini, DevTools mengekspos mekanisme yang disebut “Async Stack Tagging API” pada objek console
, yang memungkinkan developer framework memberikan petunjuk tentang lokasi tempat operasi dijadwalkan serta tempat operasi ini dijalankan.
Async Stack Tagging API
Tanpa Pemberian Tag Stack Asinkron, pelacakan tumpukan untuk kode yang dieksekusi secara asinkron dengan cara yang kompleks oleh framework, akan muncul tanpa koneksi ke kode tempat kode tersebut dijadwalkan.
Dengan Pemberian Tag Stack Asinkron, Anda dapat memberikan konteks ini, dan pelacakan tumpukan akan terlihat seperti ini:
Untuk mencapai hal ini, gunakan metode console
baru bernama console.createTask()
yang disediakan oleh Async Stack Tagging API. Tanda tangannya adalah sebagai berikut:
interface Console {
createTask(name: string): Task;
}
interface Task {
run<T>(f: () => T): T;
}
Memanggil console.createTask()
akan menampilkan instance Task
yang nantinya dapat Anda gunakan untuk menjalankan kode asinkron.
// Task Creation
const task = console.createTask(name);
// Task Execution
task.run(f);
Operasi asinkron juga dapat disusun bertingkat, dan “penyebab utama” akan ditampilkan dalam stack trace secara berurutan.
Tugas dapat dijalankan sebanyak mungkin dan payload pekerjaan dapat berbeda di antara setiap operasi. Stack panggilan di situs penjadwalan akan diingat hingga objek tugas dihapus.
Async Stack Tagging API di Angular
Di Angular, perubahan telah dilakukan pada NgZone – konteks eksekusi Angular yang tetap ada di seluruh tugas asinkron.
Saat menjadwalkan tugas, console.createTask()
akan digunakan jika tersedia. Instance Task
yang dihasilkan disimpan untuk digunakan lebih lanjut. Setelah memanggil tugas, NgZone akan menggunakan instance Task
yang disimpan untuk menjalankannya.
Perubahan ini diterapkan di NgZone 0.11.8 Angular melalui permintaan pull #46693 dan #46958.
Bingkai Panggilan yang Ramah
Framework sering kali menghasilkan kode dari berbagai jenis bahasa template saat mem-build project, seperti template Angular atau JSX yang mengubah kode yang terlihat seperti HTML menjadi JavaScript biasa yang pada akhirnya berjalan di browser. Terkadang, jenis fungsi yang dihasilkan ini diberi nama yang tidak terlalu mudah — baik nama satu huruf setelah diminifikasi atau beberapa nama yang tidak jelas atau tidak dikenal meskipun tidak.
Di Angular, tidak jarang melihat frame panggilan dengan nama seperti AppComponent_Template_app_button_handleClick_1_listener
dalam pelacakan tumpukan.
Untuk mengatasi hal ini, Chrome DevTools kini mendukung penggantian nama fungsi ini melalui peta sumber. Jika peta sumber memiliki entri nama untuk awal cakupan fungsi (yaitu, tanda kurung kiri daftar parameter), frame panggilan akan menampilkan nama tersebut dalam pelacakan tumpukan.
Frame Panggilan yang Ramah di Angular
Mengganti nama frame panggilan di Angular adalah upaya yang berkelanjutan. Kami berharap peningkatan ini akan diluncurkan secara bertahap dari waktu ke waktu.
Saat mengurai template HTML yang telah ditulis penulis, compiler Angular akan menghasilkan kode TypeScript, yang pada akhirnya ditranspile menjadi kode JavaScript yang dimuat dan dijalankan browser.
Sebagai bagian dari proses pembuatan kode ini, peta sumber juga dibuat. Saat ini kami sedang mempelajari cara menyertakan nama fungsi di kolom “names” pada peta sumber, dan mereferensikan nama tersebut dalam pemetaan antara kode yang dihasilkan dan kode asli.
Misalnya, jika fungsi untuk pemroses peristiwa dibuat dan namanya tidak mudah dipahami atau dihapus selama minifikasi, peta sumber kini dapat menyertakan nama yang lebih mudah dipahami untuk fungsi ini di kolom "nama" dan pemetaan untuk awal cakupan fungsi kini dapat merujuk ke nama ini (yaitu, tanda kurung kiri dari daftar parameter). Chrome DevTools kemudian akan menggunakan nama ini untuk mengganti nama frame panggilan dalam pelacakan tumpukan.
Rencana ke depan
Menggunakan Angular sebagai uji coba untuk memverifikasi pekerjaan kami adalah pengalaman yang luar biasa. Kami ingin mendengar pendapat dari developer framework dan memberikan masukan tentang titik ekstensi ini.
Ada lebih banyak area yang ingin kami jelajahi. Secara khusus, cara meningkatkan pengalaman pembuatan profil di DevTools.