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

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

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

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

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

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

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

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

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

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

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

استخدِم الخيارات التالية لمناقشة الميزات الجديدة أو التحديثات أو أي شيء آخر متعلّق بـ "أدوات مطوّري البرامج".