המדריך הזה מתמקד בשינויים משמעותיים שנוספו בגרסה 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מתעלמת מפרמטר השאילתה של כתובת ה-URLfbclidכשהיא מחפשת תגובה שנשמרה במטמון לבקשה נתונה.
- ה-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.