เมื่อใช้ Workbox คุณอาจต้องการจัดการคำขอและการตอบกลับเมื่อมีการดึงข้อมูลหรือแคช ปลั๊กอิน Workbox ช่วยให้คุณเพิ่มลักษณะการทํางานเพิ่มเติมให้กับ Service Worker ได้โดยต้องมีต้นแบบเพิ่มเติมน้อยที่สุด คุณสามารถจัดทำเป็นแพ็กเกจและนํามาใช้ในโปรเจ็กต์ของคุณเอง หรือจะเผยแพร่ต่อสาธารณะเพื่อให้ผู้อื่นใช้ด้วยก็ได้
Workbox มีปลั๊กอินมากมายให้เลือกใช้ และถ้าคุณถนัดในความชำนาญ คุณสามารถเขียนปลั๊กอินที่กำหนดเองซึ่งปรับแต่งให้เหมาะกับความต้องการของแอปพลิเคชันของคุณได้
ปลั๊กอิน Workbox ที่ใช้ได้
Workbox มีปลั๊กอินอย่างเป็นทางการต่อไปนี้สำหรับใช้ใน Service Worker
BackgroundSyncPlugin
: หากคำขอเครือข่ายล้มเหลว ปลั๊กอินนี้จะช่วยให้คุณเพิ่มคำขอดังกล่าวลงในคิวการซิงค์เบื้องหลังเพื่อให้ขอได้อีกครั้งเมื่อมีการเรียกใช้เหตุการณ์การซิงค์ครั้งถัดไปBroadcastUpdatePlugin
: ช่วยให้คุณส่งข้อความผ่านช่องประกาศหรือผ่านpostMessage()
เมื่อมีการอัปเดตแคชCacheableResponsePlugin
: เฉพาะคำขอแคชที่ตรงกับเกณฑ์ที่ระบุExpirationPlugin
: จัดการจำนวนและอายุสูงสุดของรายการในแคชRangeRequestsPlugin
: ตอบกลับคำขอที่มีส่วนหัวของคำขอ HTTPRange
ปลั๊กอิน 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
: เรียกใช้เมื่อใดก็ตามที่คำขอเครือข่ายสำเร็จ โดยไม่คำนึงถึงโค้ดตอบกลับ HTTPhandlerWillStart
: มีการเรียกใช้ก่อนที่ตรรกะของตัวแฮนเดิลจะเริ่มทำงาน ซึ่งจะเป็นประโยชน์หากจำเป็นต้องตั้งค่าสถานะตัวแฮนเดิลเริ่มต้น ตัวอย่างเช่น หากต้องการทราบเวลาที่ตัวแฮนเดิลใช้เวลาสร้างการตอบกลับ คุณก็อาจจดบันทึกเวลาเริ่มต้นในโค้ดเรียกกลับนี้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 จากชุมชน
cloudinary-workbox-plugin
ซึ่งเขียนคำขอใหม่แบบไดนามิกสำหรับรูปภาพที่โฮสต์บนระบบคลาวด์ตามความเร็วในการเชื่อมต่อปัจจุบันworkbox-plugin-firebase-auth
ช่วยจัดการAuthorization: Bearer
สำหรับคำขอขาออกที่ต้องมีการตรวจสอบสิทธิ์ Firebase
คุณอาจค้นหาปลั๊กอิน Workbox เพิ่มเติมจากชุมชนได้โดยค้นหาในที่เก็บของ npm
สุดท้าย ถ้าคุณสร้างปลั๊กอิน Workbox ที่ต้องการแชร์ ให้เพิ่มคีย์เวิร์ด workbox-plugin
เมื่อเผยแพร่ โปรดแจ้งให้เราทราบทาง Twitter @WorkboxJS