העברת ה-Puppeteer ל-TypeScript

אנחנו מעריכים מאוד את TypeScript בצוות של כלי הפיתוח – עד כדי כך שכותבים בו קוד חדש בכלי הפיתוח, ואנחנו נמצאים בעיצומו של תהליך העברה גדול של כל ה-codebase שבו מתבצעת בדיקת הקלדה על ידי TypeScript. אפשר לקרוא מידע נוסף על ההעברה הזו בשיחה שלנו בכנס Chrome Dev Community 2020. לכן, היה הגיוני לבדוק גם את ההעברה של קוד הבסיס של Puppeteer ל-TypeScript.

תכנון ההעברה

כשתכננו את תהליך ההעברה, רצינו להתקדם בצעדים קטנים. כך אפשר לצמצם את התקורה של ההעברה – אתם עובדים רק על חלק קטן מהקוד בכל פעם – וגם לצמצם את הסיכון. אם משהו משתבש באחת מהפעולות, אפשר לבטל אותה בקלות. ל-Puppeteer יש הרבה משתמשים, ופרסום גרסה עם באגים יגרום לבעיות אצל רבים מהם. לכן היה חשוב לנו לצמצם את הסיכון לשינויים שגורמים לשיבושים למינימום.

גם אנחנו התמזל מזלנו של-Puppeteer יש סדרה של בדיקות יחידה מתקדמות שמטפלת בכל הפונקציונליות שלה. המשמעות היא שיכולנו להיות בטוחים שלא היינו מפירים את הקוד במהלך המעבר, אבל גם לא הוספנו שינויים ב-API. המטרה של ההעברה הייתה להשלים את התהליך בלי שמשתמשי Puppeteer יבינו בכלל שעברנו לגרסה החדשה, והבדיקות היו חלק חיוני באסטרטגיה הזו. אם לא הייתה לנו כיסוי בדיקה טוב, היינו מוסיפים אותו לפני שנמשיך בהעברה.

ביצוע שינוי בקוד ללא בדיקות הוא מסוכן, אבל שינויים כאשר נוגעים בקבצים שלמים או בכל ה-codebase הם מסוכנים במיוחד. כשמבצעים שינויים מכניים, קל לפספס שלב כלשהו, ומספר פעמים, הבדיקות זיהו בעיה שחלתה על פני המיישם והבודק.

דבר אחד שבו השקענו זמן מראש היה הגדרת האינטגרציה הרצייפה (CI). שמנו לב שהפעלת CI נגד בקשות משיכה הייתה לא יציבה ולרוב נכשלה. זה קרה כל כך הרבה פעמים עד שהתרגלנו להתעלם מה-CI שלנו ולמזג את בקשות המשיכה, בהנחה שהכשל היה בעיה חד-פעמית ב-CI ולא בעיה ב-Puppeteer.

אחרי קצת תחזוקה כללית וזמן ייעודי לתיקון כמה שגיאות רגילות בבדיקות, הצלחנו להגיע למצב שבו הבדיקה עוברת באופן עקבי הרבה יותר, וכך אנחנו יכולים להקשיב ל-CI ולדעת שכשיש כשל, מדובר בבעיה אמיתית. זה לא תהליך מרהיב, ועצוב לראות את מספר ההרצות האינסופיות של ה-CI, אבל היה חיוני שחבילת הבדיקות תפעל בצורה מהימנה, בהתחשב במספר בקשות ה-pull שההעברה זרקה עליה.

בוחרים קובץ אחד ומקבלים אותו

בשלב הזה כבר היינו מוכנים להעברה, ויצרנו שרת CI חזק שמלא בבדיקות כדי שנוכל לעקוב אחרינו. במקום להתמקד בקובץ שרירותי כלשהו, בחרנו בכוונה קובץ קטן להעברה. זהו תרגיל שימושי מכיוון שהוא מאפשר לכם לאמת את התהליך המתוכנן שאתם עומדים לבצע. אם הפתרון פועל בקובץ הזה, הגישה שלכם תקינה. אם לא, תוכלו לחזור אל לוח העבודה.

בנוסף, העובדה שבדקנו קובץ אחר קובץ (ופרסמנו גרסאות רגילות של Puppeteer, כך שכל השינויים לא נשלחו באותה גרסת npm) צמצמה את הסיכון. בחרנו ב-DeviceDescriptors.js בתור הקובץ הראשון, כי הוא היה אחד מהקבצים הפשוטים ביותר בקוד. יכול להיות שזה ייראה לכם קצת מאכזב לבצע את כל עבודת ההכנה הזו ולהגיע לשינוי קטן כל כך, אבל המטרה היא לא לבצע שינויים גדולים באופן מיידי, אלא להמשיך בזהירות ובאופן שיטתי, קובץ אחר קובץ. הזמן שהשקעתם באימות הגישה חוסכת לכם זמן בשלב מאוחר יותר בהעברה, כשמגיעים לקבצים המורכבים האלה.

מוכיחים את התבנית וחוזר חלילה

למרבה המזל, השינוי ל-DeviceDescriptors.js עבר בהצלחה לקוד הבסיסי והתוכנית פעלה כמו שקיווינו. בשלב הזה אתם מוכנים להתחיל לעבוד, וזה בדיוק מה שעשינו. שימוש בתווית GitHub הוא דרך נהדרת לקבץ יחד את כל בקשות המשיכה, וגילינו שזה שימושי למעקב אחר ההתקדמות.

העברה של הנתונים ושיפורם בהמשך

התהליך שלנו בכל קובץ JavaScript היה:

  1. שינוי שם הקובץ מ-.js ל-.ts.
  2. מריצים את המהדר של TypeScript.
  3. פותרים את הבעיות.
  4. יוצרים את בקשת המשיכה.

רוב העבודה בבקשות ה-pull הראשוניות האלה הייתה לחלץ ממשקי TypeScript למבני נתונים קיימים. במקרה של בקשת ה-pull הראשונה שהעבירה את 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.

אנחנו מהנדסים שעובדים על קוד הבסיס של Puppeteer, וכבר נהנינו מאוד מ-TypeScript. בשילוב עם סביבת ה-CI המשופרת שלנו, הדבר אפשר לנו לשפר את הפרודוקטיביות בעבודה על Puppeteer ולאפשר ל-TypeScript לזהות באגים, שאחרת היו נכנסים למהדורה של npm. אנחנו שמחים לשלוח הגדרות TypeScript באיכות גבוהה כדי לאפשר לכל המפתחים שמשתמשים ב-Puppeteer ליהנות מהעבודה הזו גם כן.

הורדת הערוצים לתצוגה מקדימה

מומלץ להשתמש ב-Chrome Canary, ב-Dev או ב-Beta כדפדפן הפיתוח שמוגדר כברירת מחדל. ערוצי התצוגה המקדימה האלה מעניקים לכם גישה לתכונות העדכניות ביותר של DevTools, מאפשרים לכם לבדוק ממשקי API מתקדמים לפלטפורמות אינטרנט ולמצוא בעיות באתר לפני שהמשתמשים שלכם יעשו זאת.

יצירת קשר עם צוות כלי הפיתוח ל-Chrome

אפשר לבחור מבין האפשרויות הבאות כדי לדון בתכונות החדשות, בעדכונים או בכל נושא אחר שקשור לכלי פיתוח.