תיבת עבודה-Sw

המודול של workbox-sw מאפשר להתחיל לעבוד בקלות עם המודולים של Workbox, ומפשט את הטעינה של המודולים של Workbox ומספר שיטות עזר פשוטות.

ניתן להשתמש ב-workbox-sw דרך רשת ה-CDN שלנו, או עם קבוצה של קבצים של תיבת העבודה בשרת שלכם.

שימוש ב-Workbox SW דרך CDN

הדרך הקלה ביותר להתחיל להשתמש במודול הזה היא באמצעות CDN. כל מה שצריך לעשות הוא להוסיף את הפקודה הבאה ל-Service Worker:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

כך יהיה לכם מרחב השמות של workbox ב-Service Worker, שיאפשר גישה לכל המודולים של Workbox.

workbox.precaching.*
workbox.routing.*
etc

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

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

מתבצעת טעינה של ספריות תיבת העבודה בכלי הפיתוח

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

שימוש בקובצי תיבת עבודה מקומיים במקום ב-CDN

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

הגישה הפשוטה ביותר היא לקבל את הקבצים באמצעות הפקודה copyLibraries של workbox-cli, ואז לומר ל-workbox-sw איפה למצוא את הקבצים האלה באמצעות אפשרות ההגדרה modulePathPrefix.

אם תציבו את הקבצים מתחת ל-/third_party/workbox-vX.Y.Z/, הם ישמשו באופן הבא:

importScripts('/third_party/workbox-vX.Y.Z/workbox-sw.js');

workbox.setConfig({
  modulePathPrefix: '/third_party/workbox-vX.Y.Z/',
});

הימנעות מייבוא אסינכרוני

כדי לבצע טעינה ראשית, טעינה של מודולים חדשים בפעם הראשונה כרוכה בקריאה ל-importScripts() עם הנתיב לקובץ ה-JavaScript המתאים (שמתארח ב-CDN או דרך כתובת URL מקומית). בכל מקרה, חלה הגבלה חשובה: קריאות משתמעות ל-importScripts() יכולות להתרחש רק בתוך ה-handler של install של Service Worker או במהלך ההפעלה הראשונית הסינכרונית של הסקריפט של קובץ השירות (service worker).

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

לדוגמה, הקוד של קובץ השירות (service worker) ברמה העליונה יכול להיות תקין:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will work!
workbox.routing.registerRoute(
  ({request}) => request.destination === 'image',
  new workbox.strategies.CacheFirst()
);

אבל הקוד הבא יכול להיות בעייתי אם לא הזכרתם את workbox.strategies במקום אחר ב-service worker:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Oops! This causes workbox-strategies.js to be imported inside a fetch handler,
    // outside of the initial, synchronous service worker execution.
    const cacheFirst = new workbox.strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

אם אתם צריכים לכתוב קוד שאחרת עלול להפר את ההגבלה הזו, תוכלו להפעיל באופן מפורש את הקריאה importScripts() מחוץ ל-handler של האירועים באמצעות השיטה workbox.loadModule():

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will trigger the importScripts() for workbox.strategies and its dependencies:
workbox.loadModule('workbox-strategies');

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Referencing workbox.strategies will now work as expected.
    const cacheFirst = new workbox.strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

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

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will trigger the importScripts() for workbox.strategies and its dependencies:
const {strategies} = workbox;

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Using the previously-initialized strategies will work as expected.
    const cacheFirst = new strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

אילוץ שימוש בניפוי באגים או בגרסאות ייצור

לכל המודולים של Workbox יש שתי גרסאות build – גרסת build לניפוי באגים שכוללת רישום ביומן ובדיקת סוגים נוספת, וגרסת build של סביבת הייצור ששומרת את הרישום ביומן ובדיקת סוגי הפריטים.

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

אם רוצים לאלץ ניפוי באגים או גרסאות build לייצור, אפשר להגדיר את אפשרות ההגדרה debug:

workbox.setConfig({
  debug: true,
});

המרת הקוד באמצעות הצהרות ייבוא לשימוש ב-workbox-sw

כשטוענים את Workbox באמצעות workbox-sw, הגישה לכל חבילות Workbox מתבצעת דרך מרחב השמות הגלובלי workbox.*.

אם יש לכם דוגמת קוד שמשתמשת בהצהרות import שאתם רוצים להמיר כדי להשתמש ב-workbox-sw, כל מה שתצטרכו לעשות הוא לטעון את workbox-sw ולהחליף את כל ההצהרות import במשתנים מקומיים שמפנים למודולים האלה במרחב השמות הגלובלי.

הסיבה לכך היא שכל חבילת Worker של Workbox שפורסמה ב-Npm זמינה גם במרחב השמות הגלובלי workbox באמצעות גרסת camelCase של השם (למשל, ניתן למצוא ב-workbox.precaching.* את כל המודולים שיוצאו מחבילת ה-NPM של workbox-precaching. ואת כל המודולים שיוצאו מחבילת ה-NPM workbox-background-sync תוכלו למצוא ב-workbox.backgroundSync.*).

כדוגמה, זו דוגמה לקוד שמשתמש בהצהרות import שמתייחסות למודולים של תיבת עבודה:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponse} from 'workbox-cacheable-response';

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
  })
);

הנה אותו קוד שנכתב מחדש כדי להשתמש ב-workbox-sw (שימו לב שרק הצהרות הייבוא השתנו - הלוגיקה לא השתנתה):

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

const {registerRoute} = workbox.routing;
const {CacheFirst} = workbox.strategies;
const {CacheableResponse} = workbox.cacheableResponse;

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
  })
);