การใช้ปลั๊กอิน

เมื่อใช้ Workbox คุณอาจต้องการจัดการคำขอและการตอบกลับเมื่อมีการดึงข้อมูลหรือแคช ปลั๊กอิน Workbox ช่วยให้คุณเพิ่มลักษณะการทํางานเพิ่มเติมให้กับ Service Worker ได้โดยต้องมีต้นแบบเพิ่มเติมน้อยที่สุด คุณสามารถจัดทำเป็นแพ็กเกจและนํามาใช้ในโปรเจ็กต์ของคุณเอง หรือจะเผยแพร่ต่อสาธารณะเพื่อให้ผู้อื่นใช้ด้วยก็ได้

Workbox มีปลั๊กอินมากมายให้เลือกใช้ และถ้าคุณถนัดในความชำนาญ คุณสามารถเขียนปลั๊กอินที่กำหนดเองซึ่งปรับแต่งให้เหมาะกับความต้องการของแอปพลิเคชันของคุณได้

ปลั๊กอิน Workbox ที่ใช้ได้

Workbox มีปลั๊กอินอย่างเป็นทางการต่อไปนี้สำหรับใช้ใน Service Worker

  • BackgroundSyncPlugin: หากคำขอเครือข่ายล้มเหลว ปลั๊กอินนี้จะช่วยให้คุณเพิ่มคำขอดังกล่าวลงในคิวการซิงค์เบื้องหลังเพื่อให้ขอได้อีกครั้งเมื่อมีการเรียกใช้เหตุการณ์การซิงค์ครั้งถัดไป
  • BroadcastUpdatePlugin: ช่วยให้คุณส่งข้อความผ่านช่องประกาศหรือผ่าน postMessage() เมื่อมีการอัปเดตแคช
  • CacheableResponsePlugin: เฉพาะคำขอแคชที่ตรงกับเกณฑ์ที่ระบุ
  • ExpirationPlugin: จัดการจำนวนและอายุสูงสุดของรายการในแคช
  • RangeRequestsPlugin: ตอบกลับคำขอที่มีส่วนหัวของคำขอ HTTP Range

ปลั๊กอิน Workbox ไม่ว่าจะเป็นปลั๊กอินใดปลั๊กอินหนึ่งที่ระบุไว้ข้างต้นหรือเป็นปลั๊กอินที่กำหนดเอง ใช้กับกลยุทธ์กล่องงานได้โดยการเพิ่มอินสแตนซ์ของปลั๊กอินไปยังพร็อพเพอร์ตี้ plugins ของกลยุทธ์ ดังนี้

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {ExpirationPlugin} from 'workbox-expiration';

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    cacheName: 'images',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 60,
        maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
      }),
    ],
  })
);

วิธีการสำหรับปลั๊กอินที่กำหนดเอง

ปลั๊กอิน Workbox ต้องใช้ฟังก์ชันเรียกกลับอย่างน้อย 1 รายการ เมื่อคุณเพิ่มปลั๊กอินลงในกลยุทธ์ ฟังก์ชันเรียกกลับจะทำงานในเวลาที่เหมาะสมโดยอัตโนมัติ กลยุทธ์จะส่งข้อมูลที่เกี่ยวข้องกับคำขอและ/หรือการตอบกลับปัจจุบันไปยังฟังก์ชันเรียกกลับ เพื่อให้บริบทที่จำเป็นในการดำเนินการ ระบบรองรับฟังก์ชันเรียกกลับต่อไปนี้

  • cacheWillUpdate: เรียกใช้ก่อนที่จะมีการใช้ Response เพื่ออัปเดตแคช ในวิธีนี้ คุณสามารถเปลี่ยนแปลงการตอบกลับได้ก่อนที่จะเพิ่มแคช หรือแสดงผล null เพื่อหลีกเลี่ยงการอัปเดตแคชทั้งหมด
  • cacheDidUpdate: เรียกใช้เมื่อมีการเพิ่มรายการใหม่ในแคชหรือเมื่อมีการอัปเดตรายการที่มีอยู่ ปลั๊กอินที่ใช้วิธีนี้อาจเป็นประโยชน์เมื่อคุณต้องการทำงานหลังจากการอัปเดตแคช
  • cacheKeyWillBeUsed: เรียกใช้ก่อนที่จะใช้คำขอเป็นคีย์แคช กรณีนี้เกิดขึ้นสำหรับทั้งการค้นหาแคช (เมื่อ mode คือ 'read') และการเขียนแคช (เมื่อ mode คือ 'write') การเรียกกลับนี้จะมีประโยชน์ในกรณีที่คุณต้องการลบล้างหรือปรับค่า URL ให้เป็นมาตรฐานก่อนที่จะใช้เพื่อเข้าถึงแคช
  • cachedResponseWillBeUsed: เรียกใช้โค้ดนี้ก่อนที่จะใช้การตอบสนองจากแคช ซึ่งช่วยให้คุณตรวจสอบการตอบกลับนั้นได้ ในตอนนี้ คุณสามารถส่งคืนคำตอบอื่นหรือแสดงผล null ได้
  • requestWillFetch: โทรเมื่อคำขอกำลังจะไปยังเครือข่าย ซึ่งมีประโยชน์เมื่อคุณต้องเปลี่ยน Request ก่อนที่จะไปยังเครือข่าย
  • fetchDidFail: เรียกใช้เมื่อคำขอเครือข่ายไม่สำเร็จ ซึ่งน่าจะเป็นเพราะไม่มีการเชื่อมต่อเครือข่าย และจะไม่เริ่มทำงานเมื่อเบราว์เซอร์มีการเชื่อมต่อเครือข่าย แต่ได้รับข้อผิดพลาด (เช่น 404 Not Found)
  • fetchDidSucceed: เรียกใช้เมื่อใดก็ตามที่คำขอเครือข่ายสำเร็จ โดยไม่คำนึงถึงโค้ดตอบกลับ HTTP
  • handlerWillStart: มีการเรียกใช้ก่อนที่ตรรกะของตัวแฮนเดิลจะเริ่มทำงาน ซึ่งจะเป็นประโยชน์หากจำเป็นต้องตั้งค่าสถานะตัวแฮนเดิลเริ่มต้น ตัวอย่างเช่น หากต้องการทราบเวลาที่ตัวแฮนเดิลใช้เวลาสร้างการตอบกลับ คุณก็อาจจดบันทึกเวลาเริ่มต้นในโค้ดเรียกกลับนี้
  • handlerWillRespond: เรียกใช้ก่อนเมธอด handle() ของกลยุทธ์จะแสดงการตอบกลับ ซึ่งจะเป็นประโยชน์หากคุณต้องแก้ไขคําตอบก่อนแสดงการตอบกลับเป็น RouteHandler หรือตรรกะที่กําหนดเองอื่นๆ
  • handlerDidRespond: เรียกใช้หลังจากที่เมธอด handle() ของกลยุทธ์แสดงผลการตอบกลับ ซึ่งจะเป็นประโยชน์ในการบันทึกรายละเอียดการตอบกลับสุดท้าย (เช่น หลังการเปลี่ยนแปลงโดยปลั๊กอินอื่นๆ)
  • handlerDidComplete: เรียกใช้หลังจากที่มีสัญญาเพิ่มเติมตลอดอายุการใช้งานที่เพิ่มลงในเหตุการณ์จากการเรียกใช้กลยุทธ์แล้ว ซึ่งจะเป็นประโยชน์หากคุณต้องการรายงานข้อมูลที่ต้องรอจนกว่าตัวจัดการจะเสร็จสิ้นเพื่อคำนวณสิ่งต่างๆ เช่น สถานะการพบแคช เวลาในการตอบสนองของแคช เวลาในการตอบสนองของเครือข่าย และข้อมูลที่เป็นประโยชน์อื่นๆ
  • handlerDidError: มีการเรียกใช้หากตัวแฮนเดิลไม่สามารถให้การตอบสนองที่ถูกต้องจากแหล่งที่มาใดๆ ซึ่งเป็นเวลาที่เหมาะสมที่สุดในการมอบการตอบกลับสำรองบางอย่างเพื่อเป็นทางเลือกสำหรับความล้มเหลวโดยตรง

โค้ดเรียกกลับเหล่านี้ทั้งหมดคือ async ดังนั้นจึงต้องใช้ await ทุกครั้งที่เหตุการณ์แคชหรือการดึงข้อมูลถึงจุดที่เกี่ยวข้องสําหรับ Callback ที่กังวล

หากปลั๊กอินใช้โค้ดเรียกกลับข้างต้นทั้งหมด นี่จะเป็นโค้ดผลลัพธ์

const myPlugin = {
  cacheWillUpdate: async ({request, response, event, state}) => {
    // Return `response`, a different `Response` object, or `null`.
    return response;
  },
  cacheDidUpdate: async ({
    cacheName,
    request,
    oldResponse,
    newResponse,
    event,
    state,
  }) => {
    // No return expected
    // Note: `newResponse.bodyUsed` is `true` when this is called,
    // meaning the body has already been read. If you need access to
    // the body of the fresh response, use a technique like:
    // const freshResponse = await caches.match(request, {cacheName});
  },
  cacheKeyWillBeUsed: async ({request, mode, params, event, state}) => {
    // `request` is the `Request` object that would otherwise be used as the cache key.
    // `mode` is either 'read' or 'write'.
    // Return either a string, or a `Request` whose `url` property will be used as the cache key.
    // Returning the original `request` will make this a no-op.
    return request;
  },
  cachedResponseWillBeUsed: async ({
    cacheName,
    request,
    matchOptions,
    cachedResponse,
    event,
    state,
  }) => {
    // Return `cachedResponse`, a different `Response` object, or null.
    return cachedResponse;
  },
  requestWillFetch: async ({request, event, state}) => {
    // Return `request` or a different `Request` object.
    return request;
  },
  fetchDidFail: async ({originalRequest, request, error, event, state}) => {
    // No return expected.
    // Note: `originalRequest` is the browser's request, `request` is the
    // request after being passed through plugins with
    // `requestWillFetch` callbacks, and `error` is the exception that caused
    // the underlying `fetch()` to fail.
  },
  fetchDidSucceed: async ({request, response, event, state}) => {
    // Return `response` to use the network response as-is,
    // or alternatively create and return a new `Response` object.
    return response;
  },
  handlerWillStart: async ({request, event, state}) => {
    // No return expected.
    // Can set initial handler state here.
  },
  handlerWillRespond: async ({request, response, event, state}) => {
    // Return `response` or a different `Response` object.
    return response;
  },
  handlerDidRespond: async ({request, response, event, state}) => {
    // No return expected.
    // Can record final response details here.
  },
  handlerDidComplete: async ({request, response, error, event, state}) => {
    // No return expected.
    // Can report any data here.
  },
  handlerDidError: async ({request, event, error, state}) => {
    // Return a `Response` to use as a fallback, or `null`.
    return fallbackResponse;
  },
};

ออบเจ็กต์ event ที่มีอยู่ในโค้ดเรียกกลับที่ระบุไว้ด้านบนเป็นเหตุการณ์เดิมที่ทริกเกอร์การดำเนินการดึงข้อมูลหรือแคช บางครั้งอาจไม่มีเหตุการณ์เดิม ดังนั้นโค้ดของคุณควรตรวจสอบว่ามีเหตุการณ์อยู่หรือไม่ก่อนที่จะอ้างอิง

โค้ดเรียกกลับของปลั๊กอินทั้งหมดจะส่งผ่านออบเจ็กต์ state ด้วย ซึ่งจะไม่ซ้ำกันสำหรับปลั๊กอินบางรายการและกลยุทธ์ที่ปลั๊กอินเรียก ซึ่งหมายความว่าคุณจะเขียนปลั๊กอินโดยให้โค้ดเรียกกลับทำงานอย่างมีเงื่อนไขโดยอิงตามสิ่งที่โค้ดเรียกกลับอีกรายการในปลั๊กอินเดียวกันทำ (เช่น คำนวณความแตกต่างระหว่างการเรียกใช้ requestWillFetch() และ fetchDidSucceed() หรือ fetchDidFail())

ปลั๊กอินของบุคคลที่สาม

หากคุณพัฒนาปลั๊กอินและคิดว่ามีการใช้ปลั๊กอินนอกโปรเจ็กต์ เราขอสนับสนุนให้คุณเผยแพร่เป็นโมดูล ด้านล่างนี้เป็นรายการสั้นๆ ของปลั๊กอิน Workbox จากชุมชน

คุณอาจค้นหาปลั๊กอิน Workbox เพิ่มเติมจากชุมชนได้โดยค้นหาในที่เก็บของ npm

สุดท้าย ถ้าคุณสร้างปลั๊กอิน Workbox ที่ต้องการแชร์ ให้เพิ่มคีย์เวิร์ด workbox-plugin เมื่อเผยแพร่ โปรดแจ้งให้เราทราบทาง Twitter @WorkboxJS