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

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

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

ปลั๊กอิน Workbox ที่พร้อมใช้งาน

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

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

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

  • 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: เรียกใช้หากตัวแฮนเดิลให้คําตอบที่ถูกต้องจากแหล่งที่มาใดๆ ไม่ได้ ซึ่งเป็นเวลาที่เหมาะที่สุดในการให้คําตอบสำรองแทนที่จะให้คําตอบที่ไม่ถูกต้อง

Callback ทั้งหมดนี้คือ 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