نقل بيانات Puppeteer إلى TypeScript

جاك فرانكلين
جاك فرانكلين

نحن من كبار المعجبين بـ TypeScript في فريق أدوات مطوّري البرامج، لدرجة أنه تتم كتابة التعليمات البرمجية الجديدة في أدوات مطوري البرامج في هذا الفريق، ونحن في منتصف عملية نقل كبيرة لقاعدة الترميز بالكامل إلى أن يتم فحص نوعها بواسطة TypeScript. يمكنك الاطّلاع على مزيد من المعلومات حول عملية النقل هذه في محادثتنا في مؤتمر Chrome Dev Summit لعام 2020. لذا، كان من المنطقي أن ننظر في إمكانية نقل قاعدة رموز Puppeteer إلى TypeScript أيضًا.

التخطيط لعملية نقل البيانات

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

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

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

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

بعد بعض الصيانة العامة وتخصيص الوقت لإصلاح بعض رقاقات الاختبار المنتظمة، وصلنا إلى حالة نجاح أكثر اتساقًا، ما سمح لنا بالاستماع إلى CI ومعرفة أن الإخفاق كان يشير إلى مشكلة فعلية. هذا العمل لا يلفت النظر، ويزعجك مشاهدة عدد لا يحصى من عمليات تنفيذ اختبارات CI، ولكن كان من الضروري تشغيل مجموعة الاختبار بشكل موثوق مع الأخذ في الاعتبار عدد طلبات السحب التي كانت مصدرها عملية النقل.

اختيار ملف واحد وإرساله

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

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

إثبات النمط وتكرار العملية

لحسن الحظ، تم إجراء التغيير على "DeviceDescriptors.js" بنجاح ضمن قاعدة الرموز، وقد نجحت الخطة على النحو المرجو. في هذه المرحلة، أنت جاهز للانطلاق نحو الهدف الجديد، وهذا هو ما فعلناه بالضبط. يعد استخدام تسمية GitHub طريقة لطيفة حقًا لتجميع جميع طلبات السحب معًا، ووجدنا أنها مفيدة لتتبع التقدم.

نقل البيانات وتحسينها لاحقًا

بالنسبة إلى أي ملف JavaScript فردي، كانت العملية:

  1. أعِد تسمية الملف من .js إلى .ts.
  2. شغِّل المحول البرمجي لـ TypeScript.
  3. أصلح أي مشاكل.
  4. أنشئ طلب السحب.

كان معظم العمل في طلبات السحب الأولية هذه هو استخراج واجهات TypeScript لهياكل البيانات الحالية. في حال طلب السحب الأول الذي نقل بيانات DeviceDescriptors.js الذي ناقشناه سابقًا، انتقل الرمز من:

module.exports = [
  { 
    name: 'Pixel 4',
    … // Other fields omitted to save space
  }, 
  …
]

وأصبح:

interface Device {
  name: string,
  …
}

const devices: Device[] = [{name: 'Pixel 4', …}, …]

module.exports = devices;

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

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

ترحيل الاختبارات لاختبار تعريفات الأنواع لدينا

بعد نقل رمز المصدر بالكامل إلى TypeScript، يمكننا التركيز على اختباراتنا. اتسمت اختباراتنا بتغطية جيدة، ولكن تمت كتابتها جميعًا بلغة JavaScript. وهذا يعني أن الشيء الوحيد الذي لم يختبرونه هو تعريفات النوع. يتمثل أحد أهداف المشروع طويلة المدى (الذي ما زلنا نعمل عليه) في تقديم تعريفات الأنواع عالية الجودة بطريقة غير تقليدية باستخدام Puppeteer، ولكن لم يكن لدينا أي عمليات تحقق في قاعدة الرموز لدينا بشأن تعريفات الأنواع.

من خلال نقل الاختبارات إلى TypeScript (باتباع العملية نفسها، الانتقال إلى ملف واحد)، وجدنا مشاكل في TypeScript والتي كانت ستُترك ليجدها المستخدمون، لولا ذلك. والآن لا تشمل اختباراتنا جميع وظائفنا فحسب، بل تعمل كاختبار لجودة TypeScript أيضًا!

لقد استفدنا بشكل كبير من TypeScript كمهندسين يعملون في قاعدة الرموز Puppeteer. إلى جانب بيئة CI المحسّنة بدرجة كبيرة، تمكّنا من أن نصبح أكثر إنتاجية عند العمل على Puppeteer وقد سمح لنا TypeScript باكتشاف الأخطاء التي كانت ستتحول إلى إصدار npm. يسعدنا أن يتم شحن تعريفات TypeScript عالية الجودة لمساعدة جميع مطوّري البرامج الذين يستخدمون Puppeteer في الاستفادة من هذا العمل أيضًا.

تنزيل قنوات المعاينة

يمكنك استخدام إصدار Canary أو إصدار مطوّري البرامج أو الإصدار التجريبي من Chrome ليكون متصفِّح التطوير التلقائي. تتيح لك قنوات المعاينة هذه الوصول إلى أحدث ميزات أدوات مطوّري البرامج، واختبار واجهات برمجة التطبيقات المتطورة للأنظمة الأساسية للويب، والعثور على المشاكل في موقعك الإلكتروني قبل أن يتمكّن المستخدمون من ذلك.

التواصل مع فريق "أدوات مطوري البرامج في Chrome"

يمكنك استخدام الخيارات التالية لمناقشة الميزات والتغييرات الجديدة في المشاركة، أو أي موضوع آخر مرتبط بـ "أدوات مطوري البرامج".

  • يمكنك إرسال اقتراحات أو ملاحظات إلينا عبر crbug.com.
  • يمكنك الإبلاغ عن مشكلة في "أدوات مطوري البرامج" باستخدام خيارات إضافية   المزيد > مساعدة > الإبلاغ عن مشاكل في "أدوات مطوري البرامج" في "أدوات مطوري البرامج".
  • نشر تغريدة على @ChromeDevTools
  • يمكنك إضافة تعليقات على الميزات الجديدة في الفيديوهات على YouTube في "أدوات مطوري البرامج" أو الفيديوهات على YouTube التي تتضمّن نصائح حول أدوات مطوّري البرامج.