یک تجربه رفع اشکال بهبود یافته
طی چند ماه گذشته، تیم Chrome DevTools با تیم Angular همکاری کرد تا تجربه اشکالزدایی را در Chrome DevTools بهبود بخشد. افراد هر دو تیم با هم کار کردند و گامهایی برداشتند تا توسعهدهندگان را قادر به اشکالزدایی و نمایهسازی اپلیکیشنهای وب از منظر نویسندگی کنند : از نظر زبان مبدأ و ساختار پروژه، با دسترسی به اطلاعاتی که برای آنها آشنا و مرتبط است.
این پست نگاهی به زیر میاندازد تا ببیند برای رسیدن به این هدف، چه تغییراتی در Angular و Chrome DevTools لازم است. اگرچه برخی از این تغییرات از طریق Angular نشان داده می شوند، اما می توان آنها را در سایر فریم ورک ها نیز اعمال کرد. تیم Chrome DevTools سایر چارچوبها را تشویق میکند تا APIهای کنسول جدید و نقاط افزونه نقشه منبع را اتخاذ کنند تا آنها نیز بتوانند تجربه اشکالزدایی بهتری را به کاربران خود ارائه دهند.
کد فهرست بندی را نادیده بگیرید
هنگام اشکالزدایی برنامهها با استفاده از Chrome DevTools، نویسندگان معمولاً فقط میخواهند فقط کد آنها را ببینند، نه چارچوب زیر یا برخی وابستگیها را که در پوشه node_modules
پنهان شده است.
برای رسیدن به این هدف، تیم DevTools افزونهای را برای نقشههای منبع معرفی کرده است که x_google_ignoreList
نام دارد. این برنامه افزودنی برای شناسایی منابع شخص ثالث مانند کد چارچوب یا کد تولید شده توسط بستهکننده استفاده میشود. وقتی چارچوبی از این پسوند استفاده میکند، نویسندگان اکنون بهطور خودکار از کدهایی که نمیخواهند ببینند یا از آن عبور کنند، بدون نیاز به پیکربندی دستی از قبل، اجتناب میکنند.
در عمل، Chrome DevTools میتواند بهطور خودکار کدهای شناسایی شده را در ردیابی پشته، درخت منابع، گفتگوی باز سریع پنهان کند و همچنین رفتار گامگذاری و از سرگیری را در اشکالزدا بهبود بخشد.
پسوند نقشه منبع x_google_ignoreList
در نقشههای منبع، فیلد x_google_ignoreList
جدید به آرایه sources
اشاره دارد و شاخصهای همه منابع شناخته شده شخص ثالث را در آن نقشه منبع فهرست میکند. هنگام تجزیه نقشه منبع، Chrome DevTools از این مورد استفاده می کند تا بفهمد کدام بخش از کد باید نادیده گرفته شود.
در زیر یک نقشه منبع برای یک فایل 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 DevTools این فایلها را بهطور پیشفرض در سراسر Debugger نمایش میدهد:
- به عنوان فایل در درخت Sources.
- به عنوان نتیجه در گفتگوی باز سریع.
- به عنوان مکانهای فریم تماس نگاشت شده در خطا، ردیابیها را در حین مکث در نقطه توقف و در حین پلهگذاری، پشته میکنند.
یک اطلاعات اضافی وجود دارد که اکنون می تواند در نقشه های منبع گنجانده شود تا مشخص شود کدام یک از آن منابع کد اول یا شخص ثالث است:
{
...
"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],
...
}
اگر یک توسعهدهنده فریمورک یا بستهبندی هستید، مطمئن شوید که نقشههای منبع تولید شده در طول فرآیند ساخت شامل این فیلد میشوند تا به این قابلیتهای جدید در ابزار توسعه کروم متصل شوید.
x_google_ignoreList
در Angular
از Angular نسخه 14.1.0 ، محتویات node_modules
و پوشههای webpack
بهعنوان «نادیدهگرفتن» علامتگذاری شدهاند.
این از طریق تغییر در angular-cli
با ایجاد یک افزونه که به ماژول Compiler
وب پک متصل میشود به دست آمد.
افزونه بسته وب که مهندسان ما ایجاد کردهاند، به مرحله PROCESS_ASSETS_STAGE_DEV_TOOLING
متصل میشود و قسمت 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
. این به طور پیش فرض در آن موارد انجام می شود، بنابراین توسعه دهندگان می توانند از قبل این موارد را بررسی کنند! اما در پروژههای پیچیدهتر، به این سادگی نیست، بهویژه زمانی که از چارچوبی با مکانیسمهای زمانبندی پیشرفتهتر استفاده میشود - برای مثال، چارچوبی که ردیابی منطقه، صفبندی وظایف سفارشی را انجام میدهد، یا بهروزرسانیها را به چندین واحد از کار تقسیم میکند. زمان
برای رفع این مشکل، DevTools مکانیزمی به نام «Async Stack Tagging API» را در شی console
نشان میدهد، که به توسعهدهندگان فریمورک امکان میدهد هم مکانهایی را که عملیاتها برنامهریزی میشوند و هم به مکانهایی که این عملیات اجرا میشوند اشاره کنند.
Async Stack Tagging API
بدون Async Stack Tagging، ردیابیهای پشتهای برای کدهایی که بهصورت ناهمزمان به روشهای پیچیده توسط فریمورکها اجرا میشوند، بدون اتصال به کدی که برنامهریزی شده بود، نشان داده میشوند.
با Async Stack Tagging می توان این زمینه را فراهم کرد و stack trace به شکل زیر است:
برای رسیدن به این هدف، از یک روش console
جدید به نام console.createTask()
استفاده کنید که Async Stack Tagging API ارائه می کند. امضای آن به شرح زیر است:
interface Console {
createTask(name: string): Task;
}
interface Task {
run<T>(f: () => T): T;
}
فراخوانی console.createTask()
یک نمونه Task
برمی گرداند که بعداً می توانید از آن برای اجرای کد async استفاده کنید.
// Task Creation
const task = console.createTask(name);
// Task Execution
task.run(f);
عملیات ناهمزمان همچنین می تواند تودرتو باشد و "علل ریشه" به ترتیب در ردیابی پشته نمایش داده می شود.
وظایف را می توان هر تعداد بار اجرا کرد و بار کار می تواند بین هر اجرا متفاوت باشد. پشته تماس در سایت زمانبندی تا زمانی که شیء وظیفه جمعآوری شود، به خاطر سپرده میشود.
Async Stack Tagging API در Angular
در Angular، تغییراتی در NgZone ایجاد شده است - زمینه اجرای Angular که در تمام وظایف غیر همگام باقی می ماند.
هنگام برنامه ریزی یک کار، در صورت موجود بودن، از console.createTask()
استفاده می کند. نمونه Task
به دست آمده برای استفاده بیشتر ذخیره می شود. پس از فراخوانی وظیفه، NgZone از نمونه Task
ذخیره شده برای اجرای آن استفاده می کند.
این تغییرات در NgZone 0.11.8 Angular از طریق درخواستهای کشش #46693 و #46958 وارد شدند.
فریم های تماس دوستانه
فریمورکها معمولاً هنگام ساخت یک پروژه کد را از انواع زبانهای قالب تولید میکنند، مانند قالبهای Angular یا JSX که کدهای HTML را به جاوا اسکریپت ساده تبدیل میکنند که در نهایت در مرورگر اجرا میشود. گاهی اوقات، به این نوع توابع تولید شده نامهایی داده میشود که چندان دوستانه نیستند - یا نامهای تک حرفی پس از کوچکسازی یا برخی نامهای مبهم یا ناآشنا حتی زمانی که نیستند.
در Angular دیدن فریم های تماس با نام هایی مانند AppComponent_Template_app_button_handleClick_1_listener
در ردیابی های پشته غیر معمول نیست.
برای رفع این مشکل، Chrome DevTools اکنون از تغییر نام این توابع از طریق نقشه های منبع پشتیبانی می کند. اگر نقشه منبع یک ورودی نام برای شروع محدوده تابع (یعنی قسمت چپ لیست پارامترها) داشته باشد، فریم تماس باید آن نام را در ردیابی پشته نمایش دهد.
فریم های تماس دوستانه در Angular
تغییر نام فریم های تماس در Angular یک تلاش مداوم است. ما انتظار داریم که این پیشرفتها به تدریج در طول زمان انجام شود.
در حین تجزیه قالب های HTML که نویسندگان نوشته اند، کامپایلر Angular کد TypeScript را تولید می کند که در نهایت به کد جاوا اسکریپت تبدیل می شود که مرورگر بارگیری و اجرا می کند.
به عنوان بخشی از این فرآیند تولید کد، نقشه های منبع نیز ایجاد می شوند. ما در حال حاضر در حال بررسی راه هایی برای گنجاندن نام توابع در قسمت "نام" نقشه های منبع، و ارجاع آن نام ها در نگاشت بین کد تولید شده و کد اصلی هستیم.
به عنوان مثال، اگر تابعی برای شنونده رویداد ایجاد شود و نام آن غیردوستانه باشد یا در حین کوچکسازی حذف شود، نقشههای منبع اکنون میتوانند نام دوستانهتر برای این تابع را در قسمت «نامها» و نقشهبرداری برای ابتدای تابع قرار دهند. scope اکنون می تواند به این نام (یعنی قسمت چپ لیست پارامترها) اشاره کند. Chrome DevTools سپس از این نامها برای تغییر نام فریمهای تماس در ردیابی پشته استفاده میکند.
نگاه به جلو
استفاده از Angular به عنوان یک آزمایشی آزمایشی برای تأیید کار ما یک تجربه فوق العاده بوده است. ما دوست داریم از توسعه دهندگان فریمورک بشنویم و بازخورد خود را در مورد این نقاط توسعه ارائه دهند .
مناطق بیشتری وجود دارد که ما می خواهیم آنها را بررسی کنیم. به طور خاص، نحوه بهبود تجربه پروفایل در DevTools.