دراسة حالة: تصحيح الأخطاء في Angular بشكل أفضل باستخدام أدوات مطوري البرامج

تجربة تصحيح أخطاء محسَّنة

على مدار الأشهر القليلة الماضية، تعاون فريق "أدوات مطوري البرامج في Chrome" مع فريق Angular لإطلاق تحسينات على تجربة تصحيح الأخطاء في "أدوات مطوري البرامج في Chrome". عمل أعضاء من كلا الفريقين معًا واتخذوا خطوات من أجل تمكين المطوّرين من تصحيح الأخطاء في تطبيقات الويب وتصنيفها من منظور المؤلف: من حيث اللغة المصدر وبنية المشروع، مع إمكانية الوصول إلى معلومات مألوفة ذات صلة بهم.

تُلقي هذه المشاركة نظرةً متعمّقة لمعرفة التغييرات المطلوبة في Angular وChrome DevTools لتحقيق ذلك. على الرغم من أنه يتم إظهار بعض هذه التغييرات من خلال Angular، إلا أنه يمكن تطبيقها على أطر عمل أخرى أيضًا. يشجع فريق "أدوات مطوري البرامج في Chrome" أُطر العمل الأخرى على اعتماد واجهات برمجة التطبيقات الجديدة لوحدة التحكّم ونقاط إضافة خريطة المصادر ليتمكّنوا أيضًا من تقديم تجربة أفضل عند تصحيح الأخطاء للمستخدمين.

رمز قائمة التجاهل

عند تصحيح أخطاء التطبيقات باستخدام "أدوات مطوري البرامج في Chrome"، لا يريد المؤلفون عمومًا سوى الاطّلاع على الرموز البرمجية الخاصة بهم فقط، وليس رمز إطار العمل أسفله أو بعض العناصر التبعية المخفية في مجلد "node_modules".

لتحقيق ذلك، قدّم فريق "أدوات مطوري البرامج" إضافة إلى خرائط المصادر باسم x_google_ignoreList. تُستخدَم هذه الإضافة لتحديد مصادر الجهات الخارجية، مثل رمز إطار العمل أو الرمز الذي تنشئه أداة الحِزم. عندما يستخدم إطار عمل هذه الإضافة، يتجنّب المؤلفون الآن تلقائيًا الرموز التي لا يريدون رؤيته أو الدخول إليها بدون الحاجة إلى ضبط ذلك مسبقًا يدويًا.

من الناحية العملية، يمكن أن تخفي "أدوات مطوري البرامج في Chrome" تلقائيًا الرمز الذي تم تحديده على هذا النحو في عمليات تتبُّع تسلسل استدعاء الدوال البرمجية وشجرة المصادر ومربّع حوار "فتح سريع"، كما يمكن أن تحسن سلوك الانتقال واستئناف التشغيل في برنامج تصحيح الأخطاء.

صورة GIF متحرّكة تعرض "أدوات مطوري البرامج" قبلها وبعدها. تجدر الإشارة إلى أنّ أداة "أدوات مطوري البرامج" في الصورة التالية تعرض الرمز المؤلف في العرض التدرّجي ولم تعُد تقترح أي ملف من ملفات إطار العمل في القائمة "فتح سريع"، بل تعرض تتبُّع تسلسل استدعاء الدوال البرمجية بدقة أكبر على اليسار.

إضافة 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".

x_google_ignoreList بتنسيق Angular

بدءًا من الإصدار 14.1.0 من Angular، تم وضع علامة على محتوى المجلدَين 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. يتم ذلك تلقائيًا في هذه الحالات، لذلك يمكن للمطوّرين فحصها من قبل. ولكن في المشاريع الأكثر تعقيدًا، لا يكون الأمر بهذه البساطة، خاصةً عند استخدام إطار عمل يتضمّن آليات جدولة أكثر تقدّمًا، مثل النظام الذي ينفذ تتبُّع المنطقة، أو وضع المهام المخصّصة في قائمة الانتظار، أو الذي يقسم التحديثات إلى عدة وحدات عمل يتم تشغيلها بمرور الوقت.

لحلّ هذه المشكلة، تعرض "أدوات مطوري البرامج" على الكائن console آلية تُعرَف باسم "واجهة برمجة تطبيقات وضع علامات تكديس غير متزامن" (Async Stack Tagging API)، وهي تتيح لمطوّري أُطر العمل الإشارة إلى المواقع الجغرافية التي تمت جدولة العمليات فيها ومكان تنفيذ هذه العمليات أيضًا.

واجهة برمجة التطبيقات Async Stack Tagging API

بدون ميزة وضع علامات تكديس غير متزامن، تظهر عمليات تتبُّع تسلسل استدعاء الدوال البرمجية للرمز الذي يتم تنفيذه بطرق معقدة من خلال أُطر العمل بشكلٍ غير متزامن بدون اتصال بالرمز البرمجي في المكان الذي تمت جدولته زمنيًا.

يشير ذلك المصطلح إلى تتبُّع تسلسل استدعاء الدوال البرمجية لرموز برمجية غير متزامنة بدون أي معلومات عن وقت جدولتها. لا يعرض تتبُّع تسلسل استدعاء الدوال البرمجية إلا بدءًا من "requestAnimationFrame"، ولكن لا يتضمّن أي معلومات عن وقت جدولته.

باستخدام وضع علامات تكديس غير متزامن، يمكن توفير هذا السياق، ويبدو تتبع تسلسل استدعاء الدوال البرمجية كالتالي:

يشير ذلك المصطلح إلى تتبُّع تسلسل استدعاء الدوال البرمجية لرموز برمجية غير متزامنة، مع معلومات عن وقت جدولة المهمة. وعلى عكس ما كنت سابقًا، تتضمّن عملية تتبُّع تسلسل استدعاء الدوال البرمجية "businessLogic" و"schedule" في تتبُّع تسلسل استدعاء الدوال البرمجية.

لتحقيق ذلك، يمكنك استخدام طريقة console جديدة باسم console.createTask()، والتي توفّرها واجهة برمجة التطبيقات Async Stack Tagging API. توقيعها على النحو التالي:

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);

يمكن أيضًا دمج العمليات غير المتزامنة، وسيتم عرض "الأسباب الجذرية" في تقرير تتبُّع تسلسل استدعاء الدوال البرمجية بالتسلسل.

يمكن تشغيل المهام بأي عدد من المرات، ويمكن أن تختلف حمولة العمل بين كل عملية تشغيل. سيتم تذكُّر تكديس الاستدعاءات في موقع الجدولة إلى أن يتم جمع البيانات غير المرغوب فيها في كائن المهمة.

واجهة برمجة التطبيقات Async Stack Tagging API في Angular

في Angular، تم إجراء تغييرات على NgZone، وهو سياق تنفيذ Angular الذي يستمر في تنفيذ المهام غير المتزامنة.

عند جدولة مهمة، يتم استخدام "console.createTask()" عند توفّرها. يتم تخزين مثيل Task الناتج لاستخدامه مجددًا. عند استدعاء المهمة، سيستخدم NgZone مثيل Task المخزن لتشغيله.

تم تطبيق هذه التغييرات على NgZone 0.11.8 في Angular من خلال طلبات السحب #46693 و#46958.

إطارات مكالمات ودية

غالبًا ما تنشئ الأطر رمزًا من جميع أنواع لغات النماذج عند إنشاء مشروع، مثل نماذج Angular أو JSX التي تحوِّل الرمز الذي يظهر بتنسيق HTML إلى رمز JavaScript عادي يتم تشغيله في النهاية في المتصفح. في بعض الأحيان، تتم تسمية هذه الأنواع من الدوال المُنشأة بأسماء غير مألوفة للغاية - إما أسماء أحرف مفردة بعد تصغيرها أو بعض الأسماء الغامضة أو غير المألوفة حتى في حال عدم توفّرها.

في Angular، ليس من الشائع ظهور إطارات استدعاء بأسماء مثل AppComponent_Template_app_button_handleClick_1_listener في عمليات تتبع تسلسل استدعاء الدوال البرمجية.

لقطة شاشة لعملية تتبُّع تسلسل استدعاء الدوال البرمجية، تتضمّن اسم دالة تم إنشاؤه تلقائيًا.

لحلّ هذه المشكلة، تتيح "أدوات مطوري البرامج في Chrome" الآن إعادة تسمية هذه الدوال من خلال خرائط المصادر. إذا كانت خريطة المصدر تحتوي على إدخال اسم لبداية نطاق الدالة (أي القوس الأيسر من قائمة المَعلمات)، يجب أن يعرض إطار الاستدعاء هذا الاسم في تقرير تتبُّع تسلسل استدعاء الدوال البرمجية.

إطارات مكالمات ودية في Angular

تعد إعادة تسمية إطارات المكالمات في Angular جهدًا مستمرًا. ونتوقّع تطبيق هذه التحسينات تدريجيًا بمرور الوقت.

أثناء تحليل نماذج HTML التي كتبها المؤلفون، ينشئ المحول البرمجي Angular رمز TypeScript ومن ثم يتم تحويله في النهاية إلى رمز JavaScript يحمّله المتصفح ويشغله.

وكجزء من عملية إنشاء الرموز هذه، يتم أيضًا إنشاء خرائط المصدر. نستكشف حاليًا طرقًا لتضمين أسماء الدوال في حقل "الأسماء" (names) في خرائط المصدر والإشارة إلى تلك الأسماء في عمليّات الربط بين الرمز الذي تمّ إنشاؤه والرمز الأصلي.

على سبيل المثال، إذا تم إنشاء دالة لمستمع إلى حدث وكان اسمها غير مناسب أو تمت إزالتها أثناء تصغير البيانات، يمكن أن تتضمّن خرائط المصدر الآن الاسم الأكثر ملاءمةً لهذه الدالة في حقل "الأسماء"، ويمكن أن يشير الربط لبداية نطاق الدالة الآن إلى هذا الاسم (أي القوس الأيسر من قائمة المَعلمات). بعد ذلك، ستستخدم "أدوات مطوري البرامج في Chrome" هذه الأسماء لإعادة تسمية إطارات الاستدعاءات في عمليات تتبُّع تسلسل استدعاء الدوال البرمجية.

نظرة مستقبلية

لقد كان استخدام Angular كبرنامج تجريبي تجريبي للتحقق من عملنا تجربة رائعة. يسعدنا معرفة ملاحظات مطوِّري أُطر العمل وتقديم ملاحظاتك بشأن نقاط الإضافات هذه.

هناك المزيد من المجالات التي نود استكشافها. وعلى وجه التحديد، كيفية تحسين تجربة إنشاء المواصفات الشخصية في "أدوات مطوري البرامج".