คู่มือนี้มุ่งเน้นที่การเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นของ Workbox v5 พร้อมด้วยตัวอย่างการเปลี่ยนแปลงที่คุณจำเป็นต้องทำเมื่ออัปเกรดจาก Workbox v4
การเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบ
เปลี่ยนชื่อปลั๊กอินแล้ว
แพ็กเกจ Workbox v4 จำนวนหนึ่งมีคลาสชื่อ Plugin
รวมอยู่ด้วย ใน v5 มีการเปลี่ยนชื่อคลาสเหล่านั้นเพื่อให้เป็นไปตามตัวระบุแพ็กเกจรูปแบบ + Plugin
ดังนี้
BackgroundSyncPlugin
BroadcastUpdatePlugin
CacheableResponsePlugin
ExpirationPlugin
RangeRequestsPlugin
การเปลี่ยนชื่อนี้จะมีผลไม่ว่าคุณจะใช้คลาสผ่านการนำเข้าโมดูลหรือผ่านเนมสเปซ workbox.*
จุดแทนที่ไฟล์ Manifest ของ Precache เริ่มต้น
ก่อนหน้านี้ เมื่อใช้เครื่องมือสร้างบิลด์ในโหมด "แทรกไฟล์ Manifest" ไฟล์โปรแกรมทำงานของบริการต้นทางจะได้รับการตรวจสอบเพื่อหา precacheAndRoute([])
โดยใช้อาร์เรย์ที่ว่างเปล่า []
เป็นตัวยึดตำแหน่งสำหรับจุดที่มีการแทรกไฟล์ Manifest แบบแคชล่วงหน้า
ใน Workbox v5 ตรรกะการแทนที่ได้เปลี่ยนแปลงไป และตอนนี้จะมีการใช้ self.__WB_MANIFEST
เป็นจุดแทรกโดยค่าเริ่มต้น
// v4:
precacheAndRoute([]);
// v5:
precacheAndRoute(self.__WB_MANIFEST);
ดังที่ระบุไว้ในการสนทนานี้ เราเชื่อว่าการเปลี่ยนแปลงนี้จะทำให้ประสบการณ์การใช้งานง่ายขึ้น ขณะเดียวกันก็ทำให้นักพัฒนาซอฟต์แวร์สามารถควบคุมวิธีใช้ไฟล์ Manifest ที่แทรกเข้ามาภายในโค้ดของโปรแกรมทำงานของบริการที่กำหนดเองได้มากขึ้น คุณเปลี่ยนสตริงแทนที่นี้ผ่านตัวเลือกการกำหนดค่า injectionPoint
ได้หากจำเป็น
การเปลี่ยนเส้นทางการนําทาง
ตัวเลือก 2 รายการที่เคยรองรับสำหรับเส้นทางการนำทาง ได้แก่ blacklist
และ whitelist
เปลี่ยนชื่อเป็น denylist
และ allowlist
ก่อนหน้านี้ workbox-routing
รองรับเมธอด registerNavigationRoute()
ซึ่งภายในได้ดำเนินการ 2 อย่างต่อไปนี้
- ตรวจพบว่าเหตุการณ์
fetch
ที่ระบุมีmode
เป็น'navigate'
หรือไม่ - หากเป็นเช่นนั้น ให้ตอบกลับคำขอนั้นโดยใช้เนื้อหาของ URL ที่ฮาร์ดโค้ดไว้ในแคชก่อนหน้านี้ โดยไม่คำนึงถึง URL ที่ไปยัง URL นั้น
นี่เป็นรูปแบบที่ใช้กันทั่วไปเมื่อใช้สถาปัตยกรรม App Shell
ขั้นตอนที่ 2 ซึ่งคือการสร้างการตอบกลับโดยการอ่านจากแคชจะไม่ตรงกับความรับผิดชอบของ workbox-routing
แต่เรามองว่าเป็นฟังก์ชันที่ควรเป็นส่วนหนึ่งของ workbox-precaching
ผ่าน createHandlerBoundToURL()
ซึ่งเป็นเมธอดใหม่ วิธีการใหม่นี้สามารถใช้ได้กับคลาส NavigationRoute
ที่มีอยู่ใน workbox-routing
เพื่อให้ได้ตรรกะเดียวกัน
หากคุณใช้ตัวเลือก navigateFallback
ในโหมด "สร้าง SW" ของเครื่องมือบิลด์ การสลับจะเกิดขึ้นโดยอัตโนมัติ หากคุณกำหนดค่าตัวเลือก navigateFallbackBlacklist
หรือ navigateFallbackWhitelist
ไว้ก่อนหน้านี้ ให้เปลี่ยนตัวเลือกเหล่านั้นเป็น navigateFallbackDenylist
หรือ navigateFallbackAllowlist
ตามลำดับ
หากใช้โหมด "แทรกไฟล์ Manifest" หรือเพียงเขียน Service Worker ด้วยตนเอง และ Service Worker v4 ของ Workbox จะเรียกใช้ registerNavigationRoute()
โดยตรง คุณจะต้องแก้ไขโค้ดเพื่อรับการทำงานที่เทียบเท่ากัน
// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';
const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
whitelist: [...],
blacklist: [...],
});
// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [...],
denylist: [...],
});
registerRoute(navigationRoute);
คุณไม่จำเป็นต้องโทรหา getCacheKeyForURL()
อีกต่อไป เนื่องจาก createHandlerBoundToURL()
จะจัดการให้คุณเอง
การนำ MakeRequest() ออกจาก workbox-strategies
การโทรไปยัง makeRequest()
ส่วนใหญ่เทียบเท่ากับการโทรหา handle()
ในคลาส workbox-strategy
วิธีนี้มีความแตกต่างกันเล็กน้อยมากจนทำให้การดูทั้ง 2 แบบฟังดูสมเหตุสมผลแต่กลับไม่สมเหตุสมผล นักพัฒนาแอปที่เรียกใช้ makeRequest()
ควรเปลี่ยนไปใช้ handle()
ได้โดยไม่มีการเปลี่ยนแปลงเพิ่มเติม
// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});
// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});
ใน v5 นั้น handle()
จะถือว่า request
เป็นพารามิเตอร์ที่จำเป็น และจะไม่กลับไปใช้ event.request
ตรวจสอบว่าคุณส่งคำขอที่ถูกต้องเมื่อเรียกใช้ handle()
workbox-broadcast-update ใช้เสมอ postMessage()
ในเวอร์ชัน 4 ไลบรารี workbox-broadcast-update
จะมีค่าเริ่มต้นเป็น Broadcast Channel API สำหรับส่งข้อความเมื่อมีการสนับสนุน และจะเปลี่ยนไปใช้ postMessage()
เฉพาะเมื่อระบบไม่รองรับช่องออกอากาศเท่านั้น
เราตระหนักว่าการต้องคอยฟังแหล่งที่มา 2 แหล่งของข้อความขาเข้า ทำให้การเขียนโค้ดฝั่งไคลเอ็นต์มีความซับซ้อนมากเกินไป นอกจากนี้ ในบางเบราว์เซอร์ การเรียกpostMessage()
จาก Service Worker ที่ส่งไปยังหน้าไคลเอ็นต์จะได้รับการบัฟเฟอร์โดยอัตโนมัติจนกว่าจะมีการตั้งค่า Listener เหตุการณ์ message
Broadcast Channel API จะไม่มีการบัฟเฟอร์เลย และข้อความที่เพิ่งประกาศจะหายไปหากส่งก่อนที่หน้าไคลเอ็นต์จะพร้อมรับ
ด้วยเหตุนี้ เราจึงเปลี่ยน workbox-broadcast-update
ให้ใช้ postMessage()
ใน v5 เสมอ ระบบจะส่งข้อความทีละรายการไปยังหน้าเว็บของไคลเอ็นต์ทั้งหมดภายในขอบเขตของ Service Worker ปัจจุบัน
เพื่อรองรับลักษณะการทํางานใหม่นี้ คุณนําโค้ดที่มีอยู่ในหน้าไคลเอ็นต์ที่สร้างอินสแตนซ์ BroadcastChannel
ออก และตั้งค่า Listener เหตุการณ์ message
ใน navigator.serviceWorker
แทนได้ ดังนี้
// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
});
// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
}
});
ผู้ใช้ workbox-window
ไม่ควรต้องทำการเปลี่ยนแปลงใดๆ เนื่องจากตรรกะภายในได้รับการอัปเดตแล้วเพื่อฟังการโทร postMessage()
รายการ
เครื่องมือสร้างต้องใช้ Node.js v8 ขึ้นไป
ระบบไม่รองรับ Node.js เวอร์ชันก่อนหน้า v8 สำหรับ workbox-webpack-plugin
, workbox-build
หรือ workbox-cli
อีกต่อไป หากใช้ Node.js เวอร์ชันก่อน 8 ให้อัปเดตรันไทม์เป็นเวอร์ชันที่รองรับ
workbox-webpack-plugin ต้องมี webpack v4 ขึ้นไป
หากคุณใช้ workbox-webpack-plugin
ให้อัปเดตการตั้งค่า Webpack ให้ใช้ Webpack v4 เป็นอย่างต่ำ
ยกเครื่องตัวเลือกเครื่องมือการสร้าง
ระบบไม่รองรับพารามิเตอร์การกำหนดค่า workbox-build
, workbox-cli
และ workbox-webpack-plugin
บางรายการอีกต่อไป ตัวอย่างเช่น generateSW
จะสร้างกลุ่มรันไทม์ของ Workbox ในเครื่องให้คุณเสมอ ดังนั้นตัวเลือก importWorkboxFrom
จะไม่สมเหตุสมผลอีกต่อไป
โปรดดูรายการตัวเลือกที่สนับสนุนในเอกสารของเครื่องมือที่เกี่ยวข้อง
การนำ generateSWString ออกจาก workbox-build
โหมด generateSWString
ถูกนำออกจาก workbox-build
แล้ว เราคาดว่าการเปลี่ยนแปลงนี้จะมีผลไม่มากนัก เนื่องจากมีการใช้ภายในโดย workbox-webpack-plugin
เป็นหลัก
การเปลี่ยนแปลงที่ไม่บังคับ
การใช้การนำเข้าโมดูล
แม้ว่าการเปลี่ยนแปลงนี้จะ ก) ไม่บังคับ และ ข) เป็นไปได้ในทางเทคนิคเมื่อใช้ Workbox v4 แต่การเปลี่ยนแปลงที่คาดว่าจะมีมากที่สุดเมื่อเปลี่ยนไปใช้ v5 คือโมเดลที่ให้คุณสร้าง Service Worker แบบแพ็กเกจของคุณเองด้วยการนำเข้าโมดูลของ Workbox วิธีนี้เป็นทางเลือกในการเรียก importScripts('/path/to/workbox-sw.js')
ที่ด้านบนของ Service Worker และการใช้ Workbox ผ่านเนมสเปซ workbox.*
หากใช้เครื่องมือบิลด์ใดเครื่องมือหนึ่ง (workbox-webpack-plugin
, workbox-build
, workbox-cli
) ในโหมด "สร้าง SW" การเปลี่ยนแปลงนี้จะเกิดขึ้นโดยอัตโนมัติ เครื่องมือเหล่านี้ทั้งหมดจะแสดงผลแพ็กเกจรันไทม์ของ Workbox แบบกำหนดเองในเครื่องควบคู่กับโค้ดจริงที่จำเป็นต่อการใช้ตรรกะของโปรแกรมทำงานของบริการ ในสถานการณ์นี้จะไม่มีการพึ่งพา workbox-sw
หรือสำเนา CDN ของ Workbox อีกต่อไป รันไทม์ของ Workbox จะแบ่งออกเป็นไฟล์แยกต่างหากซึ่งควรที่จะนำมาใช้งานพร้อมกับ Service Worker (เมื่อตั้งค่าเป็น false
ซึ่งเป็นค่าเริ่มต้น) หรือรวมอยู่ในบรรทัดพร้อมกับตรรกะของโปรแกรมทำงานของบริการ (เมื่อตั้งค่าเป็น true
) ทั้งนี้ขึ้นอยู่กับค่าของการกำหนดค่า inlineWorkboxRuntime
หากคุณกำลังใช้เครื่องมือสร้างในโหมด "แทรกไฟล์ Manifest" หรือไม่ได้ใช้เครื่องมือบิลด์ของ Workbox เลย คุณสามารถดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างกลุ่มรันไทม์ของกล่องงานของคุณเองได้ในคู่มือการใช้ Bundler (Webpack/Rollup) กับ Workbox
เราเขียนเอกสารประกอบและตัวอย่างสำหรับ v5 โดยสมมติว่าโมดูลนำเข้าไวยากรณ์ แม้ว่าเนมสเปซ workbox.*
จะยังคงได้รับการรองรับใน Workbox v5 ต่อไป
การอ่านคำตอบที่เก็บไว้ล่วงหน้า
นักพัฒนาแอปบางรายต้องอ่านการตอบกลับที่แคชไว้ล่วงหน้าโดยตรงจากแคชแทนการใช้การตอบกลับโดยปริยายผ่านเมธอด precacheAndRoute()
รูปแบบทั่วไปใน v4 คือการรับคีย์แคชเฉพาะสำหรับเวอร์ชันปัจจุบันของทรัพยากรที่แคชไว้ล่วงหน้า จากนั้นส่งต่อคีย์นั้นไปพร้อมกับชื่อแคชของแคชล่วงหน้าไปยัง caches.match()
เพื่อรับ Response
เพื่อให้ขั้นตอนนี้ง่ายขึ้น workbox-precaching
ใน v5 รองรับเมธอดใหม่ที่เทียบเท่า matchPrecache()
:
// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';
const cachedResponse = await caches.match(
getCacheKeyForURL(`/somethingPrecached`),
{
cacheName: cacheNames.precache,
}
);
// v5:
import {matchPrecache} from 'workbox-precaching';
const cachedResponse = await matchPrecache(`/somethingPrecached`);
การนำไปใช้ TypeScript
ใน v5 ไลบรารีรันไทม์ของ Workbox จะเขียนด้วย TypeScript แม้ว่าเราจะยังคงเผยแพร่โมดูลและแพ็กเกจ JavaScript ที่เปลี่ยนรูปแบบแล้วเพื่อรองรับนักพัฒนาซอฟต์แวร์ที่ไม่ได้ใช้ TypeScript แต่หากใช้ TypeScript คุณควรได้รับประโยชน์จากข้อมูลประเภทที่ถูกต้องและอัปเดตอยู่เสมอจากโปรเจ็กต์ Workbox โดยตรง
ตัวอย่างการย้ายข้อมูล
ภาพประกอบคอมมิตนี้เป็นการย้ายข้อมูลที่เกี่ยวข้องพอสมควร โดยมีความคิดเห็นในบรรทัด โดยใช้ Rollup เพื่อรวมรันไทม์ของ Workbox ที่กำหนดเองไว้ใน Service Worker สุดท้าย แทนที่จะโหลดรันไทม์จาก CDN
แม้ว่ากรณีนี้จะไม่ครอบคลุมการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบทั้งหมด แต่ต่อไปนี้คือก่อนและหลังการอัปเกรดไฟล์ Service Worker หนึ่งไฟล์จาก v4 เป็น v5 รวมถึงการเปลี่ยนเป็น TypeScript
การรับความช่วยเหลือ
เราคาดว่าการย้ายข้อมูลส่วนใหญ่จะตรงไปตรงมา หากพบปัญหาที่ไม่ได้กล่าวถึงในคู่มือนี้ โปรดแจ้งให้เราทราบโดยเปิดปัญหาใน GitHub