ניפוי באגים מודרני באינטרנט בכלי הפיתוח ל-Chrome

מבוא

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

לדוגמה, רכיבים שנבנו על בסיס Angular framework נוצרים ב-TypeScript באמצעות תבניות HTML. מתחת למכסה המנוע, ה-Agular CLI ו-webpack מהדרים הכול ל-JavaScript וליצירת חבילה שנקראת, שנשלחת לדפדפן.

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

  • אתם לא רוצים לנפות באגים בקוד JavaScript שהוקטן, אלא לנפות באגים בקוד ה-JavaScript המקורי.
  • כשמשתמשים ב-TypeScript, לא רוצים לנפות באגים ב-JavaScript, צריך לנפות באגים בקוד ה-TypeScript המקורי.
  • כשמשתמשים במיפוי כמו עם Angular, Lit או JSX, לא תמיד רוצים לנפות באגים ב-DOM שנוצר. מומלץ לנפות באגים ברכיבים עצמם.

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

מפות המקור כבר מצמצמות את הפער הזה במידה מסוימת, אבל יש עוד דברים שאתם יכולים לעשות בתחום הזה – הכלים למפתחים של Chrome והסביבה העסקית.

בואו נראה!

מחבר לעומת קוד נפרס

נכון לעכשיו, במהלך ניווט בעץ הקבצים בחלונית המקורות, תוכל לראות את התוכן של החבילה מקומפלת, ולרוב מוקטנת. אלה הקבצים שהדפדפן מוריד ומריץ בפועל. כלי הפיתוח נקרא Deployed Code (קוד פריסה).

צילום מסך של עץ הקבצים בכלי הפיתוח ל-Chrome שבו מוצג הקוד שנפרס.

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

כדי לפצות על כך, עכשיו אפשר לבקש בעץ להציג את הקוד שפורסם. כך העץ דומה יותר לקובצי מקור שאתם רואים בסביבת הפיתוח המשולבת (IDE), והקבצים האלה מופרדים עכשיו מה-Deployed Code.

צילום מסך של עץ הקבצים בכלי הפיתוח ל-Chrome שבו מוצג הקוד שנוצר.

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

צילום מסך של הגדרות כלי הפיתוח.

"רק הקוד שלי"

כשמשתמשים בתלות או בפיתוח על גבי framework, הקבצים של הצד השלישי עלולים להפריע. בדרך כלל, אתם רוצים לראות רק את הקוד, ולא את זה של ספרייה של צד שלישי שמסתתרת בתיקייה node_modules.

כדי לפצות על כך, בכלי הפיתוח יש הגדרה נוספת שמופעלת כברירת מחדל: הוספה אוטומטית של סקריפטים ידועים של צד שלישי לרשימת הפריטים להתעלמות. אפשר למצוא אותה בDevTools > DevTools > DevTools.

צילום מסך של הגדרות כלי הפיתוח.

כשההגדרה הזו מופעלת, כלי הפיתוח מסתירים כל קובץ או תיקייה שסומנו על ידי framework או כלי build כיש להתעלם מהם.

החל מ-Angular v14.1.0, תוכן התיקיות node_modules ו-webpack שלה סומן ככזה. לכן, התיקיות האלה, הקבצים שבתוכו ופריטי מידע שנוצרו בתהליך הפיתוח (Artifact) של צד שלישי אחרים, לא מופיעים במקומות שונים בכלי הפיתוח.

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

קוד שמתעלמים מרשימת קריסות בדוח הקריסות

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

צילום מסך של דוח קריסות בכלי הפיתוח.

כדי לראות את כל מסגרות הקריאות של דוח הקריסות, תמיד אפשר ללחוץ על הקישור הצגת מסגרות נוספות.

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

צילום מסך של הכלי לניפוי באגים במקורות של כלי הפיתוח במהלך ניפוי הבאגים.

קוד שמתעלמים ממנו בעץ הקבצים

כדי להסתיר את הקבצים והתיקיות שכלולים ברשימת הפריטים שהמערכת מתעלמת מהם בעץ הקבצים Authored Code בחלונית מקורות, מסמנים את האפשרות הסתרת הקוד מרשימת הפריטים להתעלמות בתצוגת עץ המקורות בהגדרות > ניסויים בכלי הפיתוח.

צילום מסך של הגדרות כלי הפיתוח.

בפרויקט Angular לדוגמה, התיקיות node_modules ו-webpack מוסתרות עכשיו.

צילום מסך של עץ הקבצים בכלי הפיתוח ל-Chrome שבו מוצג הקוד 'מפורסם', אבל לא מוצגים בו מודולים של node.

קוד מהרשימה להתעלמות בתפריט 'פתיחה מהירה'

הקוד שהמערכת מתעלמת ממנו לא רק מוסתר מעץ הקבצים, אלא גם דרך התפריט 'פתיחה מהירה' (Control+P (ב-Linux/Windows) או Command+P (Mac)).

צילום מסך של כלי הפיתוח עם התפריט 'פתיחה מהירה'.

שיפורים נוספים בדוחות הקריסות

אחרי שכבר טיפלתם בדוחות הקריסות הרלוונטיים, כלי הפיתוח ל-Chrome כולל עוד יותר שיפורים בדוחות הקריסות.

מעקבי ערימה מקושרים

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

לדוגמה, הנה מתזמן פשוט מאוד בקובץ framework.js היפותטי:

function makeScheduler() {
  const tasks = [];

  return {
    schedule(f) {
      tasks.push({ f });
    },

    work() {
      while (tasks.length) {
        const { f } = tasks.shift();
        f();
      }
    },
  };
}

const scheduler = makeScheduler();

function loop() {
  scheduler.work();
  requestAnimationFrame(loop);
};

loop();

... והאופן שבו מפתח עשוי להשתמש בו בקוד שלו בקובץ example.js:

function someTask() {
  console.trace("done!");
}

function businessLogic() {
  scheduler.schedule(someTask);
}

businessLogic();

כשמוסיפים נקודת עצירה (breakpoint) בשיטה someTask או כשבודקים את נתוני המעקב המודפסים במסוף, לא מופיעים אזכורים של הקריאה ל-businessLogic() שהיו "שורש הבעיה" של הפעולה הזו.

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

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

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

Async Stack tagging API כולל שיטה console חדשה בשם console.createTask(). חתימת ה-API היא:

interface Console {
  createTask(name: string): Task;
}

interface Task {
  run<T>(f: () => T): T;
}

הקריאה console.createTask() מחזירה מופע של Task, שאפשר להשתמש בו מאוחר יותר כדי להריץ את תוכן המשימה f.

// Task Creation
const task = console.createTask(name);

// Task Execution
task.run(f);

המשימה יוצרת את הקישור בין ההקשר שבו היא נוצרה לבין ההקשר של הפונקציה האסינכרונית שמתבצעת.

הקוד שהחלת על הפונקציה makeScheduler שלמעלה, הופך להיות:

function makeScheduler() {
  const tasks = [];

  return {
    schedule(f) {
      const task = console.createTask(f.name);
      tasks.push({ task, f });
    },

    work() {
      while (tasks.length) {
        const { task, f } = tasks.shift();
        task.run(f); // instead of f();
      }
    },
  };
}

לכן, כלי הפיתוח ל-Chrome יכולים עכשיו להציג דוח קריסות טוב יותר.

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

שימו לב איך businessLogic() נכלל עכשיו בדוח הקריסות! חוץ מזה, למשימה יש שם מוכר someTask במקום requestAnimationFrame הגנרי כמו קודם.

מסגרות שיחה ידידותיות

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

בפרויקט לדוגמה, דוגמה לזה הוא AppComponent_Template_app_button_handleClick_1_listener, והוא מוצג בדוח הקריסות.

צילום מסך של דוח קריסות עם שם פונקציה שנוצר באופן אוטומטי.

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

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

במבט קדימה

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

צוות כלי הפיתוח ל-Chrome מעודד את מחברי מסגרות לאמץ את היכולות החדשות האלה. במקרה לדוגמה: Better Angular Debugging באמצעות כלי הפיתוח מוסבר איך לבצע את ההטמעה הזו.