workbox-sw

โมดูล workbox-sw เป็นวิธีที่ง่ายสุดๆ ในการเริ่มต้นใช้งาน ด้วยโมดูล Workbox จะทำให้การโหลดโมดูล Workbox ง่ายขึ้น และ จึงนำเสนอวิธีการช่วยแนะนำแบบง่ายๆ

คุณสามารถใช้ workbox-sw ผ่าน CDN ของเรา หรือใช้กับชุดไฟล์ Workbox บนเซิร์ฟเวอร์ของคุณเอง

การใช้ 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 จะตรวจหาโมดูลนี้ และโหลดโมดูลก่อนเผยแพร่ คุณจะเห็นสิ่งนี้เกิดขึ้นใน แท็บเครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บ

กำลังโหลดไลบรารีพื้นที่ทำงานในเครื่องมือสำหรับนักพัฒนาเว็บ

เบราว์เซอร์จะจัดเก็บไฟล์เหล่านี้ไว้ในแคชเพื่อให้พร้อมใช้งานในอนาคต การใช้งานแบบออฟไลน์

การใช้ไฟล์ Workbox ในเครื่องแทน 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() โดยนัยจะทำได้เพียง เกิดขึ้นภายในเครื่องจัดการ install ของ Service Worker หรือในระหว่างการซิงโครนัส การดำเนินการเริ่มต้นของสคริปต์ Service Worker

เพื่อหลีกเลี่ยงการละเมิดข้อจำกัดนี้ แนวทางปฏิบัติที่ดีที่สุดก็คือการอ้างอิง เนมสเปซ workbox.* รายการที่อยู่นอกตัวแฮนเดิลเหตุการณ์หรือฟังก์ชันแบบไม่พร้อมกัน

ตัวอย่างเช่น รหัสโปรแกรมทำงานของบริการระดับบนสุดต่อไปนี้สามารถใช้ได้

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() นอกเครื่องจัดการเหตุการณ์โดยใช้เมธอด เมธอด 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 ทั้งหมดมาพร้อมกับ 2 บิลด์ ซึ่งเป็นบิลด์การแก้ไขข้อบกพร่อง มีการบันทึกและการตรวจสอบประเภทเพิ่มเติม และบิลด์เวอร์ชันที่ใช้งานจริง จะตัดการบันทึกและการตรวจสอบประเภท

โดยค่าเริ่มต้น workbox-sw จะใช้บิลด์การแก้ไขข้อบกพร่องสำหรับเว็บไซต์ใน localhost แต่สำหรับต้นทางอื่นๆ โมเดลจะใช้เวอร์ชันที่ใช้งานจริง

หากต้องการบังคับให้แก้ไขข้อบกพร่องหรือบิลด์เวอร์ชันที่ใช้งานจริง ให้ตั้งค่าการกำหนดค่า debug ตัวเลือก:

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

แปลงโค้ดโดยใช้คำสั่งการนำเข้าเพื่อใช้ workbox-sw

เมื่อโหลด Workbox โดยใช้ workbox-sw แพ็กเกจ Workbox ทั้งหมดจะเข้าถึงได้ผ่าน เนมสเปซ workbox.* ทั่วโลก

หากคุณมีตัวอย่างโค้ดที่ใช้คำสั่ง import ที่ต้องการแปลง หากต้องการใช้ workbox-sw คุณเพียงแค่โหลด workbox-sw และแทนที่คำสั่ง import ทั้งหมดด้วยตัวแปรภายในที่อ้างอิง โมดูลดังกล่าวในเนมสเปซสากล

วิธีนี้ได้ผลเนื่องจากแพ็กเกจ Service Worker ของ Workbox ทั้งหมดที่เผยแพร่ไปยัง NPM ก็เช่นเดียวกัน ใช้ได้ในเนมสเปซ workbox ทั่วโลกผ่าน ชื่อเวอร์ชัน camelCase (เช่น คุณสามารถดูโมดูลทั้งหมดที่ส่งออกจากแพ็กเกจ workbox-precaching npm ได้ที่ workbox.precaching.* และโมดูลทั้งหมดที่ส่งออกจาก ดูแพ็กเกจ workbox-background-sync npm ได้ที่ 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]})],
  })
);