คู่มือนี้มุ่งเน้นไปที่การเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบซึ่งเปิดตัวใน Workbox v6 พร้อมตัวอย่างการเปลี่ยนแปลงที่คุณต้องทำเมื่ออัปเกรดจาก Workbox v5
การเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบ
workbox-core
เมธอด skipWaiting() ใน workbox-core จะไม่เพิ่มแฮนเดิล install อีกต่อไป และเทียบเท่ากับการเรียก self.skipWaiting() เท่านั้น
จากนี้ไป ให้ใช้ self.skipWaiting() แทนเนื่องจาก skipWaiting() มีแนวโน้มที่จะถูกนำออกใน Workbox v7
workbox-precaching
- เอกสาร HTML แบบข้ามต้นทางสำหรับ URL ที่สอดคล้องกับการเปลี่ยนเส้นทาง HTTP จะใช้เพื่อตอบสนองคำขอการนำทางด้วย
workbox-precachingไม่ได้อีกต่อไป โดยทั่วไปแล้วสถานการณ์นี้ไม่ค่อยเกิดขึ้น - ตอนนี้
workbox-precachingจะไม่สนใจพารามิเตอร์การค้นหา URLfbclidเมื่อค้นหาการตอบกลับที่แคชไว้ล่วงหน้าสำหรับคำขอหนึ่งๆ - ตอนนี้ตัวสร้าง
PrecacheControllerจะรับออบเจ็กต์ที่มีพร็อพเพอร์ตี้เฉพาะเป็นพารามิเตอร์แทนสตริง ออบเจ็กต์นี้รองรับพร็อพเพอร์ตี้ต่อไปนี้cacheName(มีวัตถุประสงค์เดียวกับสตริงที่ส่งไปยังคอนสตรัคเตอร์ใน v5),plugins(แทนที่เมธอดaddPlugins()จาก v5) และfallbackToNetwork(แทนที่ตัวเลือกที่คล้ายกันซึ่งส่งไปยังcreateHandler()และ `createHandlerBoundToURL() ใน v5) - ตอนนี้เมธอด
install()และactivate()ของPrecacheControllerจะใช้พารามิเตอร์เพียง 1 รายการ ซึ่งควรตั้งค่าเป็นInstallEventหรือActivateEventที่เกี่ยวข้องตามลำดับ - นำเมธอด
addRoute()ออกจากPrecacheControllerแล้ว คุณสามารถใช้คลาสPrecacheRouteใหม่เพื่อสร้างเส้นทางที่ลงทะเบียนได้แทน - นำเมธอด
precacheAndRoute()ออกจากPrecacheControllerแล้ว (แต่ยังคงมีอยู่เป็นเมธอดตัวช่วยแบบคงที่ซึ่งส่งออกโดยโมดูลworkbox-precaching) เรานำออกเนื่องจากคุณใช้PrecacheRouteแทนได้ - นำเมธอด
createMatchCalback()ออกจากPrecacheControllerแล้ว คุณสามารถใช้PrecacheRouteใหม่แทนได้ - ระบบนำเมธอด
createHandler()ออกจากPrecacheControllerแล้ว คุณใช้พร็อพเพอร์ตี้strategyของออบเจ็กต์PrecacheControllerเพื่อจัดการคำขอแทนได้ - ระบบได้นำการส่งออก
createHandler()แบบคงที่ออกจากโมดูลworkbox-precachingแล้ว นักพัฒนาแอปควรสร้างอินสแตนซ์PrecacheControllerและใช้พร็อพเพอร์ตี้strategyแทน - ตอนนี้เส้นทางที่ลงทะเบียนกับ
precacheAndRoute()เป็นเส้นทาง "จริง" ที่ใช้คลาสRouterของworkbox-routingในเบื้องหลัง ซึ่งอาจทำให้ลำดับการประเมินเส้นทางแตกต่างออกไปหากคุณสลับการเรียกใช้registerRoute()และprecacheAndRoute()
workbox-routing
ตอนนี้เมธอด setDefaultHandler() จะใช้พารามิเตอร์ที่ 2 ที่ไม่บังคับซึ่งสอดคล้องกับเมธอด HTTP ที่ใช้ โดยค่าเริ่มต้นคือ 'GET'
- หากคุณใช้
setDefaultHandler()และคำขอทั้งหมดเป็นGETคุณก็ไม่จำเป็นต้องทำการเปลี่ยนแปลงใดๆ - หากคุณมีคำขอที่ไม่ใช่
GET(POST,PUTฯลฯ)setDefaultHandler()จะไม่ทำให้คำขอเหล่านั้นตรงกันอีกต่อไป
การกำหนดค่าบิลด์
ตัวเลือก mode สำหรับโหมด getManifest และ injectManifest ใน workbox-build และ workbox-cli ไม่ได้มีไว้เพื่อรองรับและถูกนำออกแล้ว ทั้งนี้ไม่รวมถึง workbox-webpack-plugin ซึ่งรองรับ mode ในปลั๊กอิน InjectManifest
เครื่องมือสร้างต้องใช้ Node.js v10 ขึ้นไป
workbox-webpack-plugin, workbox-build หรือ workbox-cli ไม่รองรับ Node.js เวอร์ชันก่อน v10 อีกต่อไป หากคุณใช้ Node.js เวอร์ชันเก่ากว่า v8 ให้อัปเดตรันไทม์เป็นเวอร์ชันที่รองรับ
การปรับปรุงใหม่
workbox-strategies
Workbox v6 นำเสนอวิธีใหม่สำหรับนักพัฒนาแอปบุคคลที่สามในการกำหนดกลยุทธ์ Workbox ของตนเอง วิธีนี้ช่วยให้นักพัฒนาแอปบุคคลที่สามสามารถขยาย Workbox ในลักษณะที่ตอบสนองความต้องการได้อย่างเต็มที่
คลาสพื้นฐานของกลยุทธ์ใหม่
ใน v6 คลาสกลยุทธ์ Workbox ทั้งหมดต้องขยายคลาสพื้นฐาน Strategy ใหม่ กลยุทธ์ในตัวทั้งหมดได้รับการเขียนใหม่เพื่อรองรับการดำเนินการนี้
คลาสพื้นฐาน Strategy มีหน้าที่หลัก 2 อย่าง ได้แก่
- การเรียกใช้ Lifecycle Callback ของปลั๊กอินที่ใช้ร่วมกันกับเครื่องมือจัดการกลยุทธ์ทั้งหมด (เช่น เมื่อเริ่มต้น ตอบสนอง และสิ้นสุด)
- การสร้างอินสแตนซ์ "เครื่องจัดการ" ที่สามารถจัดการสถานะสำหรับคำขอแต่ละรายการที่กลยุทธ์กำลังจัดการอยู่
คลาส "handler" ใหม่
ก่อนหน้านี้เรามีโมดูลภายในที่เรียกว่า fetchWrapper และ cacheWrapper ซึ่ง (ตามชื่อ) จะรวม API การดึงข้อมูลและแคชต่างๆ เข้ากับฮุกในวงจรของ API ซึ่งเป็นกลไกที่ช่วยให้ปลั๊กอินทำงานได้ในปัจจุบัน แต่ไม่ได้เปิดเผยให้นักพัฒนาแอปทราบ
คลาส "ตัวแฮนเดิล" ใหม่ StrategyHandler จะแสดงเมธอดเหล่านี้เพื่อให้กลยุทธ์ที่กำหนดเองสามารถเรียกใช้ fetch() หรือ cacheMatch() และเรียกใช้ปลั๊กอินที่เพิ่มลงในอินสแตนซ์กลยุทธ์โดยอัตโนมัติ
คลาสนี้ยังช่วยให้นักพัฒนาซอฟต์แวร์เพิ่ม Lifecycle Callback ที่กำหนดเองซึ่งอาจเจาะจงสำหรับกลยุทธ์ของตนได้ และจะ "ทำงานได้ทันที" กับอินเทอร์เฟซปลั๊กอินที่มีอยู่
สถานะวงจรของปลั๊กอินใหม่
ใน Workbox v5 ปลั๊กอินจะไม่มีสถานะ ซึ่งหมายความว่าหากคำขอ /index.html เรียกใช้ทั้ง Callback requestWillFetch และ cachedResponseWillBeUsed Callback ทั้ง 2 รายการนั้นจะสื่อสารกันไม่ได้ หรือแม้แต่รู้ว่าถูกเรียกใช้โดยคำขอเดียวกัน
ใน v6 ระบบจะส่งออบเจ็กต์ state ใหม่ไปยัง Callback ของปลั๊กอินทั้งหมดด้วย ออบเจ็กต์สถานะนี้จะไม่ซ้ำกันสำหรับออบเจ็กต์ปลั๊กอินนี้และการเรียกใช้กลยุทธ์นี้ (เช่น การเรียกใช้ handle()) ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์เขียนปลั๊กอินที่คอลแบ็กหนึ่งสามารถทำสิ่งต่างๆ ตามเงื่อนไขได้โดยอิงตามสิ่งที่คอลแบ็กอื่นในปลั๊กอินเดียวกันทำ (เช่น คำนวณเดลต้าเวลาระหว่างการเรียกใช้ requestWillFetch และ fetchDidSucceed หรือ fetchDidFail)
Lifecycle Callback ใหม่ของปลั๊กอิน
เราได้เพิ่ม Lifecycle Callback ของปลั๊กอินใหม่เพื่อให้นักพัฒนาแอปใช้ประโยชน์จากสถานะวงจรของปลั๊กอินได้อย่างเต็มที่ ดังนี้
handlerWillStart: เรียกใช้ก่อนที่ตรรกะของเครื่องจัดการจะเริ่มทำงาน คุณใช้ Callback นี้เพื่อตั้งค่าสถานะตัวแฮนเดิลเริ่มต้นได้ (เช่น บันทึกเวลาเริ่มต้น)handlerWillRespond: เรียกใช้ก่อนที่เมธอดhandle()ของกลยุทธ์จะแสดงผลลัพธ์ คุณสามารถใช้ Callback นี้เพื่อแก้ไขการตอบกลับนั้นก่อนที่จะส่งกลับไปยังเครื่องจัดการเส้นทางหรือตรรกะที่กำหนดเองอื่นๆhandlerDidRespond: เรียกใช้หลังจากเมธอดhandle()ของกลยุทธ์แสดงผลลัพธ์ คุณสามารถใช้ Callback นี้เพื่อบันทึกรายละเอียดการตอบกลับขั้นสุดท้าย เช่น หลังจากที่ปลั๊กอินอื่นๆ ทำการเปลี่ยนแปลงhandlerDidComplete: เรียกใช้หลังจากที่ extend lifetime promises ทั้งหมดที่เพิ่มลงในเหตุการณ์จากการเรียกใช้กลยุทธ์นี้ได้รับการจัดการแล้ว คุณสามารถใช้ Callback นี้เพื่อรายงานข้อมูลที่ต้องรอจนกว่าแฮนเดิลจะทำงานเสร็จเพื่อคำนวณ (เช่น สถานะการพบแคช เวลาในการตอบสนองของแคช เวลาในการตอบสนองของเครือข่าย)handlerDidError: เรียกใช้หากเครื่องจัดการไม่สามารถให้การตอบกลับที่ถูกต้องจากแหล่งที่มาใดๆ คุณสามารถใช้ Callback นี้เพื่อแสดงเนื้อหา "สำรอง" แทนข้อผิดพลาดเกี่ยวกับเครือข่ายได้
นักพัฒนาแอปที่ใช้กลยุทธ์ที่กำหนดเองของตนเองไม่ต้องกังวลเกี่ยวกับการเรียกใช้ Callback เหล่านี้ด้วยตนเอง เนื่องจากคลาสพื้นฐาน Strategy ใหม่จะจัดการทั้งหมด
ประเภท TypeScript ที่แม่นยำยิ่งขึ้นสำหรับเครื่องจัดการ
คำจำกัดความ TypeScript สำหรับเมธอด Callback ต่างๆ ได้รับการปรับให้เป็นมาตรฐานแล้ว ซึ่งจะช่วยให้นักพัฒนาแอปที่ใช้ TypeScript และเขียนโค้ดของตนเองเพื่อใช้หรือเรียกใช้แฮนเดิลได้รับประสบการณ์การใช้งานที่ดีขึ้น
workbox-window
เมธอด messageSkipWaiting() ใหม่
เราได้เพิ่มเมธอดใหม่ messageSkipWaiting() ลงในโมดูล workbox-window เพื่อลดความซับซ้อนของกระบวนการบอกให้ Service Worker "ที่รออยู่" เปิดใช้งาน ซึ่งมีการปรับปรุงบางอย่างดังนี้
- โดยจะเรียก
postMessage()ด้วยเนื้อหาข้อความมาตรฐานโดยพฤตินัย{type: 'SKIP_WAITING'}ซึ่ง Service Worker ที่สร้างโดย Workbox จะตรวจสอบเพื่อทริกเกอร์skipWaiting() - ระบบจะเลือก Service Worker ที่ "รอ" อยู่ที่ถูกต้องเพื่อโพสต์ข้อความนี้ แม้ว่าจะไม่ใช่ Service Worker เดียวกันกับที่ลงทะเบียน
workbox-windowไว้ก็ตาม
การนำเหตุการณ์ "ภายนอก" ออกเพื่อใช้พร็อพเพอร์ตี้ isExternal
ระบบได้นำเหตุการณ์ "ภายนอก" ทั้งหมดใน workbox-window ออกเพื่อแทนที่เหตุการณ์ "ปกติ" โดยตั้งค่าพร็อพเพอร์ตี้ isExternal เป็น true ซึ่งช่วยให้นักพัฒนาแอปที่ให้ความสำคัญกับความแตกต่างยังคงตรวจพบได้ และนักพัฒนาแอปที่ไม่จำเป็นต้องทราบก็สามารถละเว้นพร็อพเพอร์ตี้ได้
สูตร "เสนอการโหลดหน้าเว็บซ้ำให้ผู้ใช้" ที่สะอาดขึ้น
การเปลี่ยนแปลงทั้ง 2 รายการข้างต้นช่วยให้สูตร "เสนอการโหลดหน้าเว็บซ้ำสำหรับผู้ใช้" ง่ายขึ้น ดังนี้
// v6:
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
const showSkipWaitingPrompt = () => {
// This assumes a hypothetical createUIPrompt() method with
// onAccept and onReject callbacks:
const prompt = createUIPrompt({
onAccept: () => {
wb.addEventListener('controlling', () => {
window.location.reload();
});
// This will postMessage() to the waiting service worker.
wb.messageSkipWaiting();
},
onReject: () => {
prompt.dismiss();
},
});
};
// Listening for externalwaiting is no longer needed.
wb.addEventListener('waiting', showSkipWaitingPrompt);
wb.register();
}
</script>
workbox-routing
ระบบจะส่งพารามิเตอร์บูลีนใหม่ sameOrigin ไปยังฟังก์ชัน matchCallback ที่ใช้ใน workbox-routing โดยจะตั้งค่าเป็น true หากคำขอมีไว้สำหรับ URL ต้นทางเดียวกัน และเป็นเท็จในกรณีอื่นๆ
ซึ่งจะช่วยลดความซับซ้อนของ Boilerplate ทั่วไปบางอย่าง ดังนี้
// In v5:
registerRoute(
({url}) =>
url.origin === self.location.origin && url.pathname.endsWith('.png'),
new StaleWhileRevalidate({cacheName: 'local-png'})
);
// In v6:
registerRoute(
({sameOrigin, url}) => sameOrigin && url.pathname.endsWith('.png'),
new StaleWhileRevalidate({cacheName: 'local-png'})
);
matchOptions ใน workbox-expiration
ตอนนี้คุณสามารถตั้งค่า matchOptions ใน workbox-expiration ซึ่งจะส่งผ่านเป็น CacheQueryOptions ไปยังการเรียก cache.delete() ที่เกี่ยวข้อง (นักพัฒนาซอฟต์แวร์ส่วนใหญ่ไม่จำเป็นต้องทำเช่นนี้)
workbox-precaching
ใช้กลยุทธ์ Workbox
workbox-precaching ได้รับการเขียนใหม่เพื่อใช้ workbox-strategies เป็นฐาน การดำเนินการนี้ไม่ควรส่งผลให้เกิดการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบ และควรนำไปสู่ความสอดคล้องในระยะยาวที่ดีขึ้นเกี่ยวกับวิธีที่ทั้ง 2 โมดูลเข้าถึงเครือข่ายและแคช
ตอนนี้การแคชล่วงหน้าจะประมวลผลรายการทีละรายการ ไม่ใช่แบบเป็นกลุ่ม
workbox-precaching ได้รับการอัปเดตเพื่อให้มีการขอและแคชรายการในไฟล์ Manifest ของการแคชล่วงหน้าทีละรายการ แทนที่จะพยายามขอและแคชรายการทั้งหมดพร้อมกัน (ปล่อยให้เบราว์เซอร์หาวิธีจำกัดปริมาณ)
ซึ่งจะช่วยลดโอกาสที่จะเกิดข้อผิดพลาด net::ERR_INSUFFICIENT_RESOURCES ขณะแคชล่วงหน้า และยังช่วยลดการแย่งแบนด์วิดท์ระหว่างการแคชล่วงหน้ากับคำขอที่เกิดขึ้นพร้อมกันจากเว็บแอปด้วย
PrecacheFallbackPlugin ช่วยให้การสำรองข้อมูลแบบออฟไลน์ทำได้ง่ายขึ้น
ตอนนี้ workbox-precaching มี PrecacheFallbackPlugin ซึ่งใช้วิธีการใหม่ของวงจร handlerDidError ที่เพิ่มเข้ามาใน v6
ซึ่งช่วยให้ระบุ URL ที่แคชไว้ล่วงหน้าเป็น "ทางเลือกสำรอง" สำหรับกลยุทธ์หนึ่งๆ ได้ง่ายเมื่อไม่มีการตอบกลับ ปลั๊กอินจะดูแลการสร้างคีย์แคชที่ถูกต้องสำหรับ URL ที่แคชไว้ล่วงหน้า รวมถึงพารามิเตอร์การแก้ไขที่จำเป็น
ต่อไปนี้คือตัวอย่างการใช้เพื่อตอบกลับด้วย /offline.html ที่แคชไว้ล่วงหน้าเมื่อกลยุทธ์ NetworkOnly ไม่สามารถสร้างการตอบกลับสำหรับคำขอการนำทาง หรือพูดอีกอย่างก็คือการแสดงหน้า HTML ออฟไลน์ที่กำหนดเอง
import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
({request}) => request.mode === 'navigate',
new NetworkOnly({
plugins: [
new PrecacheFallbackPlugin({
fallbackURL: '/offline.html',
}),
],
})
);
precacheFallback ในการแคชรันไทม์
หากคุณใช้ generateSW เพื่อสร้าง Service Worker แทนที่จะเขียน Service Worker ด้วยตนเอง คุณสามารถใช้ตัวเลือกการกำหนดค่า precacheFallback ใหม่ใน runtimeCaching เพื่อทำสิ่งเดียวกันได้ ดังนี้
{
// ... other generateSW config options...
runtimeCaching: [{
urlPattern: ({request}) => request.mode === 'navigate',
handler: 'NetworkOnly',
options: {
precacheFallback: {
// This URL needs to be included in your precache manifest.
fallbackURL: '/offline.html',
},
},
}],
}
ขอความช่วยเหลือ
เราคาดว่าการย้ายข้อมูลส่วนใหญ่จะทำได้โดยตรง หากพบปัญหาที่ไม่ได้กล่าวถึงในคู่มือนี้ โปรดแจ้งให้เราทราบโดยเปิดประเด็นใน GitHub