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

המדריך הזה מתמקד בשינויי תוכנה שעלולים לגרום לכשלים שהוצגו ב-Workbox v6, עם דוגמאות לשינויים שצריך לבצע כשמשדרגים מ-Workbox v5.

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

workbox-core

ה-method‏ skipWaiting() ב-workbox-core לא תוסיף יותר handler של install, והיא שקולה לקריאה ל-self.skipWaiting().

מעכשיו, צריך להשתמש ב-self.skipWaiting() במקום זאת, כי סביר להניח ש-skipWaiting() יוסר ב-Workbox v7.

workbox-precaching

  • אי אפשר יותר להשתמש במסמכי HTML ממקורות שונים לכתובות URL שתואמות להפניה אוטומטית מסוג HTTP כדי למלא בקשת ניווט עם workbox-precaching. התרחיש הזה בדרך כלל לא נפוץ.
  • הפרמטר של שאילתת כתובת ה-URL‏ fbclid לא נכלל יותר ב-workbox-precaching כשמחפשים תגובה שנשמרה במטמון לבקשה נתונה.
  • ה-constructor של PrecacheController מקבל עכשיו אובייקט עם מאפיינים ספציפיים כפרמטר, במקום מחרוזת. האובייקט הזה תומך במאפיינים הבאים: cacheName (משרת את אותה מטרה כמו המחרוזת שהועברה ל-constructor בגרסה 5), plugins (מחליף את השיטה addPlugins() מגרסה 5) ו-fallbackToNetwork (מחליף את האפשרות הדומה שהועברה ל-createHandler() ול-`createHandlerBoundToURL() בגרסה 5).
  • השיטות 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

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

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

תצורת build

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

כלי פיתוח דורשים את Node.js בגרסה 10 ומעלה

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

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

workbox-strategies

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

מחלקה בסיסית של שיטה חדשה

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

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

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

מחלקה חדשה של "handler"

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

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

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

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

ב-Workbox v5, הפלאגינים הם ללא מצב (stateless). כלומר, אם בקשה ל-/index.html מפעילה גם את הקריאה החוזרת (callback) של requestWillFetch וגם את הקריאה החוזרת של cachedResponseWillBeUsed, לשתי הקריאות החוזרות האלה אין דרך לתקשר זו עם זו או אפילו לדעת שהן הופעלו על ידי אותה בקשה.

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

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

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

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

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

סוגי TypeScript מדויקים יותר ל-handlers

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

workbox-window

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

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

  • היא קוראת ל-postMessage() עם גוף ההודעה הסטנדרטי בפועל, {type: 'SKIP_WAITING'}, ש-Service Worker שנוצר על ידי Workbox בודק כדי להפעיל את skipWaiting().
  • הוא בוחר את ה-Service Worker הנכון במצב "בהמתנה" כדי לפרסם את ההודעה הזו, גם אם זה לא אותו Service Worker שאיתו נרשם 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 מאפשר החזרה למצב הראשוני (fallback) של השליפה מראש (prefetch) בקלות רבה יותר

workbox-precaching כולל עכשיו את PrecacheFallbackPlugin, שמטמיע את ה-method החדשה של מחזור החיים 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 במקום לכתוב אותו בעצמכם, אתם יכולים להשתמש באפשרות ההגדרה החדשה 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.