ย้ายข้อมูลจาก Workbox v5 ไปยัง v6

คู่มือนี้มุ่งเน้นไปที่การเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบซึ่งเปิดตัวใน 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 จะไม่สนใจพารามิเตอร์การค้นหา URL fbclid เมื่อค้นหาการตอบกลับที่แคชไว้ล่วงหน้าสำหรับคำขอหนึ่งๆ
  • ตอนนี้ตัวสร้าง 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