คู่มือนี้มุ่งเน้นที่การเปลี่ยนแปลงที่สำคัญซึ่งเปิดตัวใน 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 อย่าง ได้แก่
- การเรียกใช้การเรียกกลับวงจรชีวิตของปลั๊กอินที่ใช้ร่วมกันสำหรับตัวแฮนเดิลกลยุทธ์ทั้งหมด (เช่น เมื่อเริ่มต้น ตอบสนอง และสิ้นสุด)
- การสร้างอินสแตนซ์ "ตัวแฮนเดิล" ที่จัดการสถานะสําหรับคําขอแต่ละรายการที่กลยุทธ์จัดการอยู่
คลาส "handler" ใหม่
ก่อนหน้านี้เรามีโมดูลภายในที่เรียกว่า fetchWrapper และ cacheWrapper ซึ่ง (ตามชื่อที่บอกไว้) จะรวม API การดึงข้อมูลและแคชต่างๆ เข้ากับฮุกในวงจรของ API กลไกนี้ช่วยให้ปลั๊กอินทำงานได้ในปัจจุบัน แต่นักพัฒนาแอปจะไม่เห็นกลไกนี้
คลาส "handler" ใหม่ StrategyHandler จะแสดงเมธอดเหล่านี้เพื่อให้กลยุทธ์ที่กําหนดเองเรียก fetch() หรือ cacheMatch() และเรียกใช้ปลั๊กอินที่เพิ่มลงในอินสแตนซ์กลยุทธ์โดยอัตโนมัติ
คลาสนี้ยังช่วยให้นักพัฒนาซอฟต์แวร์เพิ่มการเรียกกลับวงจรที่กําหนดเองซึ่งอาจเจาะจงสําหรับกลยุทธ์ของตนได้ และ "ทํางานได้" กับอินเทอร์เฟซปลั๊กอินที่มีอยู่
สถานะวงจรชีวิตของปลั๊กอินใหม่
ใน Workbox v5 ปลั๊กอินจะไม่เก็บสถานะ ซึ่งหมายความว่าหากคําขอ /index.html ทริกเกอร์ทั้งการเรียกกลับ requestWillFetch และ cachedResponseWillBeUsed การเรียกกลับ 2 รายการดังกล่าวจะสื่อสารกันไม่ได้หรือแม้แต่จะไม่รู้ด้วยซ้ำว่าถูกเรียกให้แสดงโดยคําขอเดียวกัน
ใน v6 ระบบจะส่งออบเจ็กต์ state ใหม่ไปยังการเรียกกลับของปลั๊กอินทั้งหมดด้วย ออบเจ็กต์สถานะนี้จะเป็นของออบเจ็กต์ปลั๊กอินและอินโวคาชันกลยุทธ์นี้เท่านั้น (เช่น การเรียก handle()) ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์เขียนปลั๊กอินที่การเรียกกลับรายการหนึ่งสามารถทําบางอย่างแบบมีเงื่อนไขโดยอิงตามสิ่งที่การเรียกกลับรายการอื่นในปลั๊กอินเดียวกันทํา (เช่น คํานวณค่าต่างของเวลาระหว่างการเรียกใช้ requestWillFetch กับ fetchDidSucceed หรือ fetchDidFail)
Lifecycle Callback ใหม่ของปลั๊กอิน
เราได้เพิ่มการเรียกกลับวงจรของปลั๊กอินใหม่เพื่อให้นักพัฒนาแอปใช้ประโยชน์จากสถานะวงจรของปลั๊กอินได้อย่างเต็มที่
- handlerWillStart: เรียกใช้ก่อนที่ตรรกะตัวแฮนเดิลจะเริ่มทํางาน คุณสามารถเรียกใช้การเรียกกลับนี้เพื่อตั้งค่าสถานะตัวแฮนเดิลเริ่มต้น (เช่น บันทึกเวลาเริ่มต้น)
- handlerWillRespond: เรียกใช้ก่อนที่เมธอด- handle()ของกลยุทธ์จะแสดงผลลัพธ์ คุณสามารถใช้สําคัญกลับนี้เพื่อแก้ไขการตอบกลับก่อนที่จะส่งกลับไปยังตัวแฮนเดิลเส้นทางหรือตรรกะที่กำหนดเองอื่นๆ
- handlerDidRespond: เรียกใช้หลังจากที่เมธอด- handle()ของกลยุทธ์แสดงผล คุณสามารถใช้สําหรับบันทึกรายละเอียดคำตอบสุดท้าย เช่น หลังจากการเปลี่ยนแปลงโดยปลั๊กอินอื่นๆ
- handlerDidComplete: เรียกใช้หลังจากขยายระยะเวลาการรับประกันทั้งหมดที่เพิ่มลงในเหตุการณ์จากการเรียกใช้กลยุทธ์นี้เรียบร้อยแล้ว คุณสามารถเรียกใช้การเรียกกลับนี้เพื่อรายงานข้อมูลที่ต้องรอจนกว่าตัวแฮนเดิลจะเสร็จสิ้นเพื่อคํานวณ (เช่น สถานะการทํางานของแคช เวลาในการตอบสนองของแคช เวลาในการตอบสนองของเครือข่าย)
- handlerDidError: เรียกใช้หากตัวแฮนเดิลไม่สามารถให้คำตอบที่ถูกต้องจากแหล่งที่มาใดๆ คุณสามารถใช้สําคัญกลับนี้เพื่อแสดงเนื้อหา "สำรอง" แทนข้อผิดพลาดเกี่ยวกับเครือข่าย
นักพัฒนาซอฟต์แวร์ที่ใช้กลยุทธ์ที่กําหนดเองไม่ต้องกังวลเกี่ยวกับการเรียกใช้การเรียกกลับเหล่านี้ด้วยตนเอง เนื่องจากคลาสพื้นฐาน Strategy ใหม่จะจัดการทุกอย่างให้
ประเภท TypeScript ที่แม่นยำยิ่งขึ้นสำหรับตัวแฮนเดิล
คำจำกัดความ TypeScript สำหรับเมธอดการเรียกกลับต่างๆ ได้รับการทำให้เป็นมาตรฐานแล้ว ซึ่งจะช่วยให้นักพัฒนาซอฟต์แวร์ที่ใช้ 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 ที่มีต้นทางเดียวกัน และตั้งเป็นเท็จหากไม่ใช่
ซึ่งจะช่วยลดความซับซ้อนของข้อมูลทั่วไปบางส่วนได้
// 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