โมดูลช่องงาน 1 โมดูลที่ยังไม่ค่อยครอบคลุมในเอกสารประกอบนี้คือ workbox-window ซึ่งเป็นชุดโมดูลที่มีไว้เพื่อทำงานใน window เป้าหมายของโมดูลนี้คือ
- เพื่อลดความซับซ้อนในการลงทะเบียนและการอัปเดต Service Worker โดยช่วยให้นักพัฒนาแอประบุช่วงเวลาสําคัญของวงจร Service Worker ได้ ซึ่งช่วยให้ตอบสนองได้ง่ายขึ้นในช่วงเวลาดังกล่าว
- เพื่อป้องกันไม่ให้นักพัฒนาแอปทำข้อผิดพลาดที่พบบ่อย เช่น การลงทะเบียน Service Worker ในขอบเขตที่ไม่ถูกต้อง
- เพื่อลดความซับซ้อนของการรับส่งข้อความระหว่าง
windowกับขอบเขต Service Worker
กำลังนำเข้าและการใช้ workbox-window
การส่งออกที่คุณจะใช้บ่อยที่สุดจาก workbox-window คือคลาส Workbox ซึ่งจะนำเข้าในโหนดหรือจาก CDN ในหน้าเว็บก็ได้
การสร้างแพ็กเกจในเครื่อง
หากเครื่องมือเชนมี Bundler เช่น Webpack หรือ Rollup คุณรวมกลุ่ม workbox-window ไว้ในเครื่องได้
ก่อนอื่น ให้ติดตั้ง workbox-window เป็นส่วนประกอบที่ต้องใช้ในเวอร์ชันที่ใช้งานจริงของแอปพลิเคชัน
npm install workbox-window --save
จากนั้นใน JavaScript ของแอปพลิเคชัน คุณสามารถimportคลาส Workbox จาก workbox-window ได้โดยทำดังนี้
<script type="module">
import {Workbox} from 'workbox-window';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
แม้ว่า workbox-window จะค่อนข้างเล็ก แต่คุณก็สามารถแบ่งโดเมนจากตรรกะแอปพลิเคชันหลักของเว็บไซต์ได้โดยใช้ import แบบไดนามิก ซึ่งจะช่วยลดขนาดของแพ็กเกจหลักของหน้าเว็บ
<script type="module">
if ('serviceWorker' in navigator) {
const {Workbox} = await import('workbox-window');
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
การใช้ CDN
ถึงแม้จะไม่ใช่วิธีที่แนะนำ แต่วิธีที่ง่ายกว่าในการใช้ workbox-window คือการนําเข้าจาก CDN ดังนี้
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
คุณจะเห็นว่าองค์ประกอบ <script> ในตัวอย่างด้านบนใช้แอตทริบิวต์ type="module" จำเป็นต้องใช้คำสั่งนี้หากคุณต้องการใช้คำสั่ง import แบบคงที่ในเบราว์เซอร์โดยไม่มีขั้นตอนการสร้าง เบราว์เซอร์หลักทั้งหมดที่รองรับโปรแกรมทำงานของบริการยังรองรับโมดูล JavaScript ด้วย จึงสามารถแสดงโค้ดนี้ในเบราว์เซอร์ใดก็ได้ เนื่องจากเบราว์เซอร์รุ่นเก่าจะไม่สนใจองค์ประกอบ <script> ที่มีค่าแอตทริบิวต์ type เป็น "module"
การลงทะเบียน Service Worker
การลงทะเบียน Service Worker กับ workbox-window จะดำเนินการโดยใช้เมธอด register ของชั้นเรียน Workbox ดังนี้
import {Workbox} from 'workbox-window';
const wb = new Workbox('/sw.js');
wb.register();
ซึ่งอาจเหมือนกับการลงทะเบียน Service Worker ด้วยตนเองโดยใช้ navigator.serviceWorker.register แต่ Workbox.register จะรอจนกว่าเหตุการณ์ window load ก่อนที่จะลงทะเบียน Service Worker วิธีนี้เหมาะสำหรับในกรณีที่มีการแคชล่วงหน้า เพื่อหลีกเลี่ยงการช่วงชิงแบนด์วิดท์ที่ทำให้หน้าเริ่มต้นใช้งานล่าช้า
การสื่อสารระหว่าง window กับขอบเขต Service Worker
โปรแกรมทำงานของบริการมีขอบเขตของตนเองที่แยกจาก window และมีสิทธิ์เข้าถึงเฉพาะ API ชุดย่อยที่มีอยู่ใน window อย่างไรก็ตาม คุณจะสื่อสารระหว่าง window และ Service Worker ได้ workbox-window ช่วยให้การสื่อสารระหว่างขอบเขต 2 ระดับง่ายขึ้นด้วยเมธอด messageSW ของโมดูล workbox-window
Workbox ใช้รูปแบบที่เฉพาะเจาะจงสำหรับข้อความ ซึ่งเป็นออบเจ็กต์ที่มีพร็อพเพอร์ตี้ต่อไปนี้
typeเป็นสตริงที่ไม่ซ้ำกันที่ต้องระบุข้อความ รูปแบบควรเป็นตัวพิมพ์ใหญ่โดยมีขีดล่างคั่นระหว่างคำ (เช่นCACHE_URLS)metaเป็นสตริงที่ไม่บังคับซึ่งแสดงชื่อแพ็กเกจ Workbox ที่ส่งข้อความ ซึ่งโดยทั่วไปจะละเว้นไว้payloadคือพารามิเตอร์ที่ไม่บังคับซึ่งแสดงข้อมูลที่ต้องการส่ง ซึ่งจะเป็นข้อมูลประเภทใดก็ได้
ด้านล่างนี้คือตัวอย่างวิธีการทํางานของ messageSW โดยเริ่มจากโค้ดใน Service Worker
// sw.js
const SW_VERSION = '1.0.0';
self.addEventListener('message', (event) => {
if (event.data.type === 'GET_VERSION') {
event.ports[0].postMessage(SW_VERSION);
}
});
และโค้ดต่อไปนี้ในหน้าเว็บของคุณ
const wb = new Workbox('/sw.js');
wb.register();
const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);
มีหลายกรณีที่การสื่อสารระหว่าง Service Worker กับ window อาจเป็นประโยชน์ เช่น การแจ้งผู้ใช้เมื่อมีอัปเดตของโปรแกรมทำงานของบริการ สูตรดังกล่าวใช้เมธอดตัวช่วยพิเศษสําหรับ self.skipWaiting ชื่อ messageSkipWaiting ซึ่งส่งข้อความที่มีค่า type เป็น SKIP_WAITING