מעבר מתיבת עבודה מגרסה 5 לגרסה 6

המדריך הזה מתמקד בשינויים משמעותיים שנוספו בגרסה 6 של Workbox, עם דוגמאות לשינויים שצריך לבצע כשמשדרגים מגרסה 5 של Workbox.

שינויי תוכנה שעלולים לגרום לכשלים

workbox-core

השיטה skipWaiting() ב-workbox-core לא תוסיף יותר טיפול install, והיא שווה ערך לקריאה ל-self.skipWaiting() בלבד.

מעכשיו, מומלץ להשתמש ב-self.skipWaiting() במקום ב-skipWaiting(), כי סביר להניח ש-skipWaiting() יוסר בגרסה 7 של Workbox.

workbox-precaching

  • אי אפשר יותר להשתמש במסמכי HTML ממקורות שונים עבור כתובות URL שתואמות להפניה אוטומטית מסוג HTTP כדי לענות על בקשת ניווט עם workbox-precaching. התרחיש הזה הוא בדרך כלל נדיר.
  • מעכשיו, המערכת של workbox-precaching מתעלמת מפרמטר השאילתה של כתובת ה-URL fbclid כשהיא מחפשת תגובה שנשמרה במטמון לבקשה נתונה.
  • ה-constructor של PrecacheController מקבל עכשיו אובייקט עם מאפיינים ספציפיים כפרמטר שלו, במקום מחרוזת. האובייקט הזה תומך במאפיינים הבאים: cacheName (שמשמש לאותו מטרה כמו המחרוזת שהועברה למבנה ב-v5), plugins (מחליף את השיטה addPlugins() מ-v5) ו-fallbackToNetwork (מחליף את האפשרות הדומה שהועברה אל createHandler() ו-createHandlerBoundToURL() ב-v5).
  • השיטות install() ו-activate() של PrecacheController מקבלות עכשיו פרמטר אחד בלבד, שצריך להגדיר ל-InstallEvent או ל-ActivateEvent התואם, בהתאמה.
  • השיטה addRoute() הוסרה מ-PrecacheController. במקום זאת, אפשר להשתמש בכיתה החדשה PrecacheRoute כדי ליצור מסלול שאפשר יהיה לרשום לאחר מכן.
  • השיטה precacheAndRoute() הוסרה מ-PrecacheController. (היא עדיין קיימת כשיטת עזר סטטית שמיוצאת על ידי המודול workbox-precaching). הוא הוסר כי אפשר להשתמש ב-PrecacheRoute במקום זאת.
  • השיטה createMatchCalback() הוסרה מ-PrecacheController. במקום זאת, אפשר להשתמש ב-PrecacheRoute החדש.
  • השיטה createHandler() הוסרה מ-PrecacheController. במקום זאת, אפשר להשתמש במאפיין strategy של האובייקט PrecacheController כדי לטפל בבקשות.
  • הייצוא הסטטי של createHandler() כבר הוסר מהמודול workbox-precaching. במקום זאת, המפתחים צריכים ליצור מופע של PrecacheController ולהשתמש בנכס strategy שלו.
  • המסלול שרשום ב-precacheAndRoute() הוא עכשיו מסלול 'אמיתי' שמשתמש בכיתה Router של workbox-routing מתחת לפני השטח. אם תבצעו החלפה בין קריאות ל-registerRoute() ול-precacheAndRoute(), הדבר עלול להוביל לסדר הערכה שונה של המסלולים.

workbox-routing

השיטה setDefaultHandler() מקבלת עכשיו פרמטר שני אופציונלי שתואם לשיטת ה-HTTP שהיא חלה עליה, והערך שמוגדר כברירת מחדל הוא 'GET'.

  • אם אתם משתמשים ב-setDefaultHandler() וכל הבקשות שלכם הן GET, אין צורך לבצע שינויים.
  • אם יש לך בקשות שאינן GET (POST, PUT וכו'), setDefaultHandler() לא יגרום יותר להתאמה של הבקשות האלה.

הגדרת build

האפשרות mode למודדים getManifest ו-injectManifest ב-workbox-build וב-workbox-cli לא הייתה אמורה להיות נתמכת והיא הוסרה. הכלל הזה לא חל על workbox-webpack-plugin, שבו יש תמיכה ב-mode בפלאגין InjectManifest.

כלי ה-build דורשים את Node.js מגרסה 10 ואילך

גרסאות Node.js שקדמו לגרסה 10 כבר לא נתמכות ב-workbox-webpack-plugin, ב-workbox-build או ב-workbox-cli. אם אתם משתמשים בגרסה של Node.js שקדמה ל-v8, עליכם לעדכן את סביבת זמן הריצה לגרסה נתמכת.

שיפורים חדשים

workbox-strategies

בגרסה 6 של Workbox יש דרך חדשה למפתחים של צד שלישי להגדיר אסטרטגיות משלהם ב-Workbox. כך, מפתחים של צד שלישי יכולים להרחיב את Workbox באופן שמתאים לצרכים שלהם.

הכיתה הבסיסית החדשה של Strategy

בגרסה 6, כל הכיתות של אסטרטגיות Workbox צריכות להרחיב את הכיתה הבסיסית החדשה Strategy. כל האסטרטגיות המובנות נכתבו מחדש כדי לתמוך בכך.

הכיתה הבסיסית Strategy אחראית לשני דברים עיקריים:

  • קריאה להודעות חזרה (callbacks) במחזור החיים של הפלאגין שמשותפות לכל הטיפולים באסטרטגיות (למשל, כשהם מתחילים, מגיבים ומסיימים).
  • יצירת מופע 'handler' שיכול לנהל את המצב של כל בקשה ספציפית שיטת טיפול מטפלת בה.

הכיתה החדשה 'handler'

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

הכיתה החדשה 'handler',‏ StrategyHandler, תציג את השיטות האלה כדי ששיטות מותאמות אישית יוכלו לקרוא ל-fetch() או ל-cacheMatch(), ולכל הפלאגינים שנוספו למכונה של האסטרטגיה יופעל קריאה אוטומטית.

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

מצב חדש של מחזור החיים של פלאגין

ב-Workbox בגרסה 5, יישומי הפלאגין הם ללא מצב. כלומר, אם בקשה ל-/index.html מפעילה גם את פונקציית ה-callback של requestWillFetch וגם את זו של cachedResponseWillBeUsed, אין לשתי פונקציות ה-callback האלה אפשרות לתקשר זו עם זו או אפילו לדעת שהן הופעלו על ידי אותה בקשה.

בגרסה 6, כל קריאות החזרה (callbacks) של הפלאגין יקבלו גם אובייקט state חדש. אובייקט המצב הזה יהיה ייחודי לאובייקט הפלאגין הספציפי הזה ולקריאה הספציפית הזו של האסטרטגיה (כלומר, הקריאה ל-handle()). כך המפתחים יכולים לכתוב פלאגינים שבהם פונקציית קריאה חוזרת אחת יכולה לבצע משהו באופן מותנה על סמך מה שפונקציית קריאה חוזרת אחרת באותו פלאגין עשתה (למשל, חישוב הפרש הזמן בין הפעלת requestWillFetch לבין הפעלת fetchDidSucceed או fetchDidFail).

קריאות חוזרות חדשות במחזור החיים של הפלאגין

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

  • handlerWillStart: הקריאה מתבצעת לפני שהלוגיקה של הטיפול מתחילה לפעול. אפשר להשתמש בקריאה החוזרת הזו כדי להגדיר את מצב הטיפול הראשוני (למשל, לתעד את שעת ההתחלה).
  • handlerWillRespond: הקריאה מתבצעת לפני ששיטת handle() של האסטרטגיות מחזירה תשובה. אפשר להשתמש בקריאה החוזרת הזו כדי לשנות את התגובה לפני שהיא מוחזרת למטפל במסלול או ללוגיקת התאמה אישית אחרת.
  • handlerDidRespond: הקריאה מתבצעת אחרי ששיטת handle() של האסטרטגיה מחזירה תשובה. אפשר להשתמש בקריאה החוזרת הזו כדי לתעד את פרטי התשובה הסופיים, למשל אחרי שינויים שבוצעו על ידי יישומי פלאגין אחרים.
  • handlerDidComplete: הקריאה מתבצעת אחרי שהסתיימו כל ההבטחות להארכת משך החיים שנוספו לאירוע מהפעלת האסטרטגיה הזו. אפשר להשתמש בקריאה החוזרת הזו כדי לדווח על נתונים שצריך להמתין עד שהטיפול יסתיים כדי לחשב אותם (למשל, סטטוס היטים במטמון, זמן אחזור במטמון, זמן אחזור ברשת).
  • handlerDidError: הקריאה הזו מתבצעת אם הטיפול לא הצליח לספק תגובה תקפה מכל מקור. אפשר להשתמש בקריאה החוזרת הזו כדי לספק תוכן 'חלופי' כחלופה לשגיאה בחיבור לרשת.

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

סוגי TypeScript מדויקים יותר למטפלים

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

workbox-window

השיטה החדשה messageSkipWaiting()‎

הוספנו שיטה חדשה, messageSkipWaiting(), למודול workbox-window כדי לפשט את התהליך של הפיכת ה-service worker 'הממתין' לפעיל. יש לכך כמה יתרונות:

  • הוא קורא ל-postMessage() עם גוף ההודעה הסטנדרטי למעשה, {type: 'SKIP_WAITING'}, שאותו בודק עובד שירות שנוצר על ידי Workbox כדי להפעיל את skipWaiting().
  • הוא בוחר את קובץ השירות המתאים "בסטטוס המתנה" כדי לפרסם את ההודעה הזו, גם אם זה לא אותו קובץ שירות שבו workbox-window נרשם.

הסרה של אירועים 'חיצוניים' לטובת נכס isExternal

כל האירועים 'החיצוניים' ב-workbox-window הוסרו, והם הוחלפו באירועים 'רגילים' עם מאפיין isExternal שמוגדר כ-true. כך מפתחים שחשוב להם להבחין בין שני הנכסים עדיין יכולים לזהות את ההבדל, ומפתחים שלא צריכים לדעת עליו יכולים להתעלם מהנכס.

נוסחה נקייה יותר ל'הצעה למשתמשים לטעון מחדש את הדף'

בזכות שני השינויים שלמעלה, אפשר לפשט את המתכון 'הצעה למשתמשים לטעון מחדש את הדף':

// v6:
<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    const showSkipWaitingPrompt = () => {
      // This assumes a hypothetical createUIPrompt() method with
      // onAccept and onReject callbacks:
      const prompt = createUIPrompt({
        onAccept: () => {
          wb.addEventListener('controlling', () => {
            window.location.reload();
          });

          // This will postMessage() to the waiting service worker.
          wb.messageSkipWaiting();
        },

        onReject: () => {
          prompt.dismiss();
        },
      });
    };

    // Listening for externalwaiting is no longer needed.
    wb.addEventListener('waiting', showSkipWaitingPrompt);
    wb.register();
  }
</script>

workbox-routing

פרמטר בוליאני חדש, sameOrigin, מועבר לפונקציה matchCallback שמשמשת ב-workbox-routing. הערך מוגדר כ-true אם הבקשה היא לכתובת URL מאותו מקור, וכ-false במקרה אחר.

כך אפשר לפשט תבניות סטנדרטיות נפוצות:

// In v5:
registerRoute(
  ({url}) =>
    url.origin === self.location.origin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

// In v6:
registerRoute(
  ({sameOrigin, url}) => sameOrigin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

matchOptions ב-workbox-expiration

עכשיו אפשר להגדיר את matchOptions ב-workbox-expiration, והוא יועבר כ-CacheQueryOptions לקריאה הבסיסית של cache.delete(). (רוב המפתחים לא יצטרכו לעשות זאת).

workbox-precaching

שימוש ב-workbox-strategies

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

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

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

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

ה-PrecacheFallbackPlugin מאפשר חלופה קלה יותר במצב אופליין

workbox-precaching כולל עכשיו PrecacheFallbackPlugin, שמטמיע את שיטת מחזור החיים החדשה handlerDidError שנוספה בגרסה 6.

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

דוגמה לשימוש בו כדי להשיב באמצעות /offline.html שנשמר במטמון מראש, כאשר האסטרטגיה NetworkOnly לא יכולה ליצור תשובה לבקשת ניווט – במילים אחרות, הצגת דף HTML בהתאמה אישית במצב אופליין:

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
  ({request}) => request.mode === 'navigate',
  new NetworkOnly({
    plugins: [
      new PrecacheFallbackPlugin({
        fallbackURL: '/offline.html',
      }),
    ],
  })
);

precacheFallback בשמירה במטמון בזמן ריצה

אם אתם משתמשים ב-generateSW כדי ליצור בשבילכם service worker במקום לכתוב את ה-service worker בעצמכם, אתם יכולים להשתמש באפשרות ההגדרה החדשה precacheFallback ב-runtimeCaching כדי להשיג את אותו הדבר:

{
  // ... other generateSW config options...
  runtimeCaching: [{
    urlPattern: ({request}) => request.mode === 'navigate',
    handler: 'NetworkOnly',
    options: {
      precacheFallback: {
        // This URL needs to be included in your precache manifest.
        fallbackURL: '/offline.html',
      },
    },
  }],
}

קבלת עזרה

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