ย้ายข้อมูลจาก Workbox v2 ไปยัง v3

คู่มือนี้เน้นอธิบายการเปลี่ยนแปลงที่เกิดใน Workbox v3 พร้อมตัวอย่างการเปลี่ยนแปลงที่คุณต้องดำเนินการเมื่ออัปเกรดจากการตั้งค่า Workbox v2

หากคุณกำลังใช้ชุดค่าผสม sw-precache/sw-toolbox เดิมและกำลังจะเปลี่ยนไปใช้ Workbox เป็นครั้งแรก โปรดดูคำแนะนำในการย้ายข้อมูลอื่นที่จะช่วยได้

พื้นหลัง v3

รุ่น v3 ของ Workbox แสดงถึงการเปลี่ยนโครงสร้างภายในโค้ดเบสที่มีอยู่อย่างมีนัยสำคัญ เป้าหมายที่ครอบคลุมมีดังนี้

  • ลดขนาดพื้นที่ทำงาน จำนวนโค้ดรันไทม์ของ Service Worker ที่ดาวน์โหลดและดำเนินการลดลง แทนที่จะเลือกทุกคนให้เข้าร่วมแพ็กเกจขนาดโมโนลิธ ระบบจะนำเข้าเฉพาะโค้ดสำหรับฟีเจอร์ที่คุณใช้อยู่ขณะรันไทม์เท่านั้น
  • พื้นที่ทำงานมี CDN เรามีโฮสติ้ง CDN ที่ใช้ Google Cloud Storage ที่รองรับอย่างเต็มรูปแบบเป็นตัวเลือก Canonical สำหรับการเข้าถึงไลบรารีรันไทม์ของ Workbox ทำให้ง่ายต่อการเริ่มต้นใช้งาน Workbox
  • การแก้ไขข้อบกพร่องและบันทึกที่ดียิ่งขึ้น ประสบการณ์การแก้ไขข้อบกพร่องและการบันทึกได้รับการปรับปรุงขึ้นอย่างมาก ระบบจะเปิดใช้บันทึกการแก้ไขข้อบกพร่องโดยค่าเริ่มต้นเมื่อมีการใช้ Workbox จากต้นทาง localhost และระบบจะนำการบันทึกและการยืนยันทั้งหมดออกจากบิลด์เวอร์ชันที่ใช้งานจริง วันที่ ตัวอย่างการบันทึกการแก้ไขข้อบกพร่องของ Workbox v3
  • ปลั๊กอิน Webpack ที่ได้รับการปรับปรุง workbox-webpack-plugin ผสานรวมกับกระบวนการบิลด์ Webpack อย่างใกล้ชิดมากขึ้น ซึ่งช่วยให้ใช้งานแบบ Zero config ได้เมื่อคุณต้องการแคชชิ้นงานทั้งหมดล่วงหน้าในไปป์ไลน์บิลด์

การบรรลุเป้าหมายเหล่านี้และล้างบางแง่มุมของอินเทอร์เฟซก่อนหน้านี้ที่ดูอึดอัดหรือนำไปสู่รูปแบบที่เปลี่ยนไปนั้น จำเป็นต้องมีการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบหลายอย่างในรุ่น v3

การเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบ

การกำหนดค่าบิลด์

การเปลี่ยนแปลงต่อไปนี้ส่งผลต่อลักษณะการทำงานของเครื่องมือบิลด์ทั้งหมด (workbox-build, workbox-cli, workbox-webpack-plugin) ซึ่งมีชุดตัวเลือกการกำหนดค่าร่วมกัน

  • ชื่อตัวแฮนเดิล 'fastest' ถูกต้องก่อนหน้านี้ และถือเป็นชื่อแทนสำหรับ 'staleWhileRevalidate' เมื่อกำหนดค่า runtimeCaching ใช้ไม่ได้แล้ว และนักพัฒนาแอปควรเปลี่ยนไปใช้ 'staleWhileRevalidate' โดยตรง
  • มีการอัปเดตชื่อพร็อพเพอร์ตี้ runtimeCaching.options หลายชื่อและมีการตรวจสอบพารามิเตอร์เพิ่มเติมซึ่งจะทำให้บิลด์ล้มเหลวหากใช้การกำหนดค่าที่ไม่ถูกต้อง โปรดดูเอกสารประกอบสำหรับruntimeCachingเพื่อดูรายการตัวเลือกที่รองรับในปัจจุบัน

workbox-background-sync

  • ตอนนี้ระบบจะตีความพารามิเตอร์การกำหนดค่า maxRetentionTime เป็นจำนวนนาที แทนที่จะเป็นจำนวนมิลลิวินาที
  • ตอนนี้มีสตริงที่จำเป็นซึ่งแสดงชื่อคิว ซึ่งต้องส่งผ่านเป็นพารามิเตอร์แรกเมื่อสร้างคลาสปลั๊กอินหรือคลาสสแตนด์อโลน (ก่อนหน้านี้ถูกส่งต่อในฐานะคุณสมบัติของตัวเลือก) ดูเอกสารประกอบเกี่ยวกับแพลตฟอร์ม API ที่อัปเดตแล้ว

workbox-broadcast-cache-update

  • ตอนนี้ มีสตริงที่จำเป็นซึ่งแสดงชื่อช่อง ซึ่งต้องส่งผ่านเป็นพารามิเตอร์แรกเมื่อสร้างคลาสปลั๊กอินหรือคลาสสแตนด์อโลน

ตัวอย่างเช่น ใน v2 คุณจะต้องเริ่มต้นคลาสปลั๊กอินดังต่อไปนี้

new workbox.broadcastCacheUpdate.BroadcastCacheUpdatePlugin({
  channelName: 'cache-updates',
  headersToCheck: ['etag'],
});

การใช้งานที่เทียบเท่าใน v3 คือ

new workbox.broadcastUpdate.Plugin('cache-updates', {headersToCheck: ['etag']});

ดูเอกสารประกอบเกี่ยวกับแพลตฟอร์ม API ที่อัปเดตแล้ว

workbox-build

  • โดยค่าเริ่มต้น การจับคู่รูปแบบ glob จะทำงานด้วยตัวเลือก follow: true (ซึ่งจะต่อจากลิงก์สัญลักษณ์) และ strict: true (ซึ่งจะไม่ทนต่อข้อผิดพลาด "ผิดปกติ" น้อยกว่า) คุณสามารถปิดใช้และกลับสู่ลักษณะการทำงานก่อนหน้าได้โดยการตั้งค่า globFollow: false และ/หรือ globStrict: false ในการกำหนดค่าบิลด์
  • ฟังก์ชันใน workbox-build ทั้งหมดจะแสดงพร็อพเพอร์ตี้เพิ่มเติม ซึ่งก็คือ warnings ในคำตอบที่ฟังก์ชันเหล่านั้นแสดง เราอนุญาตให้บางสถานการณ์ที่ได้รับการพิจารณาว่าเป็นข้อผิดพลาดร้ายแรงใน v2 แล้ว แต่จะรายงานผ่าน warnings ซึ่งเป็นอาร์เรย์ของสตริง

ในเวอร์ชัน 2 คุณอาจเรียกใช้ generateSW เช่น

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size}) => console.log(`Precached ${count} files, totaling ${size} bytes.`))
  .catch((error) => console.error(`Something went wrong: ${error}`));

แม้ว่าคุณจะสามารถใช้โค้ดเดียวกันใน v3 แต่เราขอแนะนำให้ตรวจสอบ warnings และบันทึกไว้:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size, warnings}) => {
    for (const warning of warnings) {
      console.warn(warning);
    }
    console.log(`Precached ${count} files, totalling ${size} bytes.`);
  })
  .catch((error) => console.error(`Something went wrong: ${error}`));
  • นักพัฒนาซอฟต์แวร์ที่เขียนฟังก์ชัน ManifestTransform ที่กำหนดเองใน v2 จะต้องแสดงผลอาร์เรย์ไฟล์ Manifest ในออบเจ็กต์ (กล่าวคือ คุณควรใช้ return {manifest: manifestArray}; แทน return manifestArray;) วิธีนี้ช่วยให้ปลั๊กอินของคุณรวมพร็อพเพอร์ตี้ warnings ที่ไม่บังคับได้ ซึ่งควรเป็นอาร์เรย์ของสตริงที่มีข้อมูลคำเตือนที่ไม่ร้ายแรง

หากคุณเขียน ManifestTransform ที่กำหนดเองใน v2 โค้ด เช่น

const cdnTransform = manifestEntries => {
  return manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
};

มี v3 ที่เทียบเท่ากับ:

const cdnTransform = manifestEntries => {
  const manifest = manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
  return {manifest, warnings: []};
};
  • ฟังก์ชัน getFileManifestEntries() ได้เปลี่ยนชื่อเป็น getManifest() และคำสัญญาที่ให้ไว้ในตอนนี้รวมถึงข้อมูลเพิ่มเติมเกี่ยวกับ URL ที่มีการแคชล่วงหน้า

โค้ดต่อไปนี้มีลักษณะดังนี้ใน v2

const manifestEntries = await workboxBuild.getFileManifestEntries({...});

สามารถเขียนใหม่ใน v3 เป็น

const {manifestEntries, count, size, warnings} = await workboxBuild.getManifest({...});

// Use manifestEntries like before.
// Optionally, log the new info returned in count, size, warnings.
  • ฟังก์ชัน generateFileManifest() ถูกนำออกแล้ว ขอแนะนำให้นักพัฒนาแอปเรียกใช้ getManifest() แทน และใช้การตอบสนองของตนเองเพื่อเขียนข้อมูลลงในดิสก์ในรูปแบบที่เหมาะสม

workbox-cache-expiration

  • API ปลั๊กอินยังคงเหมือนเดิม ซึ่งเป็นโหมดที่นักพัฒนาซอฟต์แวร์ส่วนใหญ่จะนำไปใช้ อย่างไรก็ตาม มีการเปลี่ยนแปลงที่สำคัญของ API ที่ส่งผลกระทบต่อนักพัฒนาแอปที่ใช้ API แบบแยกเป็นคลาสเดี่ยว ดูเอกสารประกอบเกี่ยวกับแพลตฟอร์ม API ที่อัปเดตแล้ว

workbox-cli

นักพัฒนาซอฟต์แวร์สามารถเรียกใช้ CLI ด้วยแฟล็ก --help สำหรับชุดพารามิเตอร์ที่รองรับทั้งหมด

  • ลบการสนับสนุนชื่อแทน workbox-cli สำหรับสคริปต์ไบนารีแล้ว ตอนนี้คุณจะเข้าถึงไบนารีได้ด้วยชื่อ workbox เท่านั้น
  • คำสั่ง v2 generate:sw และ inject:manifest เปลี่ยนชื่อเป็น generateSW และ injectManifest ใน v3 แล้ว
  • ใน v2 ไฟล์การกำหนดค่าเริ่มต้น (ใช้เมื่อไม่ได้ระบุอย่างชัดเจน) คือ workbox-cli-config.js ในไดเรกทอรีปัจจุบัน ในเวอร์ชัน 3 ซึ่งเป็น workbox-config.js

เมื่อพิจารณารวมกันแล้ว จะเกิดสิ่งต่อไปนี้ในเวอร์ชัน 2

$ workbox inject:manifest

จะเรียกใช้ "แทรกไฟล์ Manifest" กระบวนการบิลด์ โดยใช้การกำหนดค่าที่อ่านจาก workbox-cli-config.js และใน v3

$ workbox injectManifest

จะทำเช่นเดียวกัน แต่อ่านการกำหนดค่าจาก workbox-config.js

การแคชล่วงหน้า

  • ก่อนหน้านี้เมธอด precache() ได้ดำเนินการทั้งการแก้ไขแคชและตั้งค่าการกำหนดเส้นทางเพื่อแสดงรายการที่แคชไว้ ตอนนี้ precache() จะแก้ไขเฉพาะรายการแคช และแสดงเมธอดใหม่ นั่นคือ addRoute() เพื่อลงทะเบียนเส้นทางเพื่อแสดงการตอบกลับที่แคชไว้เหล่านั้น นักพัฒนาแอปที่ต้องการฟังก์ชันการทำงานแบบ 2 อินวันก่อนหน้านี้สามารถเปลี่ยนไปใช้การโทรหา precacheAndRoute() ได้
  • ตอนนี้ ระบบได้ส่งตัวเลือกต่างๆ ที่เคยกำหนดค่าผ่านตัวสร้าง WorkboxSW เข้ามาเป็นพารามิเตอร์ options ใน workbox.precaching.precacheAndRoute([...], options) ค่าเริ่มต้นสำหรับตัวเลือกเหล่านั้นแม้จะไม่ได้กำหนดค่าไว้ จะแสดงอยู่ในเอกสารอ้างอิง
  • โดยค่าเริ่มต้น ระบบจะตรวจสอบ URL ที่ไม่มีนามสกุลไฟล์โดยอัตโนมัติเพื่อหารายการแคชที่มีนามสกุล .html ตัวอย่างเช่น หากมีการส่งคำขอสำหรับ /path/to/index (ซึ่งไม่ใช่แคชล่วงหน้า) และมีรายการที่แคชไว้ล่วงหน้าสำหรับ /path/to/index.html ระบบจะใช้รายการที่แคชไว้ล่วงหน้าดังกล่าว นักพัฒนาแอปสามารถปิดใช้ลักษณะการทำงานใหม่นี้โดยการตั้งค่า {cleanUrls: false} เมื่อส่งตัวเลือกไปยัง workbox.precaching.precacheAndRoute()
  • จะไม่มีการกำหนดค่าให้ workbox-broadcast-update ประกาศการอัปเดตแคชสำหรับเนื้อหาที่แคชไว้ล่วงหน้าโดยอัตโนมัติอีกต่อไป

โค้ดต่อไปนี้ใน v2

const workboxSW = new self.WorkboxSW({
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
  precacheChannelName: 'precache-updates',
});
workboxSW.precache([...]);

มี v3 ที่เทียบเท่ากับ:

workbox.precaching.addPlugins([
    new workbox.broadcastUpdate.Plugin('precache-updates')
]);

workbox.precaching.precacheAndRoute([...], {
  cleanUrls: false,
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
});

การกำหนดเส้นทางกล่องงาน

  • นักพัฒนาแอปที่ก่อนหน้านี้ใช้ workbox-routing ผ่านเนมสเปซ workbox.router.* ของออบเจ็กต์ WorkboxSW ต้องเปลี่ยนไปใช้เนมสเปซใหม่ workbox.routing.*
  • ขณะนี้เส้นทางจะได้รับการประเมินตามลำดับของการลงทะเบียนครั้งแรก นี่เป็นลำดับที่ตรงข้ามกันของการประเมิน Route ที่ใช้ใน v2 โดย Route ที่ลงทะเบียนล่าสุดจะมีความสำคัญเหนือกว่า
  • คลาส ExpressRoute และการสนับสนุนสำหรับ "Express-style" นำไวลด์การ์ดออกแล้ว ซึ่งจะลดขนาดของ workbox-routing ได้อย่างมาก สตริงที่ใช้เป็นพารามิเตอร์แรกสำหรับ workbox.routing.registerRoute() จะถือว่าตรงกันทั้งหมด ไวลด์การ์ดหรือการจับคู่ที่ตรงกันบางส่วนควรได้รับการจัดการโดย RegExp โดยการใช้ RegExp ที่ตรงกับ URL คำขอบางส่วนหรือทั้งหมดสามารถทริกเกอร์เส้นทางได้
  • นำวิธีการช่วย addFetchListener() ของชั้นเรียน Router ออกแล้ว นักพัฒนาแอปจะเพิ่มตัวแฮนเดิล fetch ของตนเองอย่างชัดแจ้ง หรือใช้อินเทอร์เฟซที่ workbox.routing จัดเตรียมไว้ให้ ซึ่งจะสร้างเครื่องจัดการ fetch โดยปริยาย
  • นำเมธอด registerRoutes() และ unregisterRoutes() ออกแล้ว เวอร์ชันของเมธอดเหล่านั้นที่ใช้กับ Route เดียวไม่มีการเปลี่ยนแปลง และนักพัฒนาซอฟต์แวร์ที่ต้องลงทะเบียนหรือยกเลิกการลงทะเบียนหลายเส้นทางพร้อมกันควรเรียกหลายๆ ครั้งไปที่ registerRoute() หรือ unregisterRoute() แทน

โค้ดต่อไปนี้ใน v2

const workboxSW = new self.WorkboxSW();

workboxSW.router.registerRoute(
  '/path/with/.*/wildcard/',
  workboxSW.strategies.staleWhileRevalidate()
);

workboxSW.router.registerRoute(
  new RegExp('^https://example.com/'),
  workboxSW.strategies.networkFirst()
);

มี v3 ที่เทียบเท่ากับ:

workbox.routing.registerRoute(
  new RegExp('^https://example.com/'),
  workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
  new RegExp('^/path/with/.*/wildcard'),
  workbox.strategies.staleWhileRevalidate()
);

Workbox-strategies (เดิมเรียกว่า workbox-runtime-caching)

  • ตอนนี้โมดูล workbox-runtime-caching มีชื่ออย่างเป็นทางการว่า workbox-strategies และได้เผยแพร่เมื่อ npm โดยใช้ชื่อใหม่
  • การใช้การหมดอายุของแคชในกลยุทธ์โดยไม่ได้ระบุชื่อแคชจะใช้ไม่ได้อีกต่อไป ใน v2 สิ่งนี้เป็นไปได้:
workboxSW.strategies.staleWhileRevalidate({
  cacheExpiration: {maxEntries: 50},
});

ปัญหานี้จะทำให้เกิดรายการที่หมดอายุในแคชเริ่มต้น ซึ่งเป็นข้อผิดพลาดที่ไม่คาดคิด ใน v3 ชื่อแคช ต้องระบุ:

workboxSW.strategies.staleWhileRevalidate({
  cacheName: 'my-cache',
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});
  • วิธีอายุการใช้งาน cacheWillMatch เปลี่ยนชื่อเป็น cachedResponseWillBeUsed แล้ว ข้อมูลนี้ไม่ควรปรากฏให้เห็นสำหรับนักพัฒนาซอฟต์แวร์ เว้นแต่นักพัฒนาจะได้เขียนปลั๊กอินของตนเองที่ตอบสนองต่อ cacheWillMatch
  • มีการเปลี่ยนแปลงไวยากรณ์สำหรับการระบุปลั๊กอินเมื่อกำหนดค่ากลยุทธ์ ปลั๊กอินแต่ละรายการต้องแสดงอย่างชัดเจนในพร็อพเพอร์ตี้ plugins ของการกำหนดค่ากลยุทธ์

โค้ดต่อไปนี้ใน v2

const workboxSW = new self.WorkboxSW();

const networkFirstStrategy = workboxSW.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  cacheExpiration: {
    maxEntries: 50,
  },
  cacheableResponse: {
    statuses: [0, 200],
  },
});

มี v3 ที่เทียบเท่ากับ:

const networkFirstStrategy = workbox.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  plugins: [
    new workbox.expiration.Plugin({maxEntries: 50}),
    new workbox.cacheableResponse.Plugin({statuses: [0, 200]}),
  ],
});

คุณสามารถเรียนรู้เพิ่มเติมได้ใน "การใช้ปลั๊กอิน"

Workbox-SW

  • workbox-sw ได้รับการเขียนใหม่ให้เป็น "ตัวโหลด" น้ำหนักเบา ซึ่งมีการกำหนดค่าพื้นฐานบางส่วนและมีหน้าที่ในการดึงโมดูลอื่นๆ ที่จำเป็นขณะรันไทม์ แทนที่จะสร้างอินสแตนซ์ใหม่ของคลาส WorkboxSW นักพัฒนาซอฟต์แวร์จะโต้ตอบกับอินสแตนซ์ที่มีอยู่ซึ่งระบบเปิดเผยในเนมสเปซส่วนกลางโดยอัตโนมัติ

ก่อนหน้านี้ใน v2:

importScripts('<path to workbox-sw>/importScripts/workbox-sw.prod.v2.1.3.js');

const workbox = new WorkboxSW({
  skipWaiting: true,
  clientsClaim: true,
  // etc.
});

workbox.router.registerRoute(...);

ใน v3 คุณเพียงแค่ต้องนำเข้าสคริปต์ workbox-sw.js และอินสแตนซ์ที่พร้อมใช้งานจะพร้อมให้ใช้งานโดยอัตโนมัติในเนมสเปซส่วนกลางเป็น workbox:

importScripts('<path to workbox-sw>/3.0.0/workbox-sw.js');

// workbox is implicitly created and ready for use.
workbox.routing.registerRoute(...);
  • ไม่มีการส่ง skipWaiting และ clientsClaim ไปยังเครื่องมือสร้าง WorkboxSW อีกต่อไป แต่จะเปลี่ยนไปใช้เมธอด workbox.clientsClaim() และ workbox.skipWaiting() แทน
  • ตัวเลือก handleFetch ที่ก่อนหน้านี้ได้รับการสนับสนุนในตัวสร้าง v2 ไม่ได้รับการสนับสนุนใน v3 อีกต่อไป นักพัฒนาซอฟต์แวร์ที่ต้องการฟังก์ชันการทำงานที่คล้ายกันเพื่อทดสอบ Service Worker โดยไม่ต้องเรียกใช้ตัวแฮนเดิลการดึงข้อมูลใดๆ สามารถใช้ฟีเจอร์ "การข้ามสำหรับเครือข่าย" ในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome
ตัวเลือก &quot;ข้ามสำหรับเครือข่าย&quot; ในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

workbox-webpack-plugin

ปลั๊กอินดังกล่าวได้รับการเขียนใหม่อย่างมาก และในหลายๆ กรณี สามารถใช้ใน "การกำหนดค่าเป็นศูนย์" ได้ ดูเอกสารประกอบเกี่ยวกับแพลตฟอร์ม API ที่อัปเดตแล้ว

  • ตอนนี้ API จะแสดง 2 คลาส ได้แก่ GenerateSW และ InjectManifest ซึ่งทำให้สลับระหว่างโหมดต่างๆ อย่างชัดแจ้งกับลักษณะการทำงานของ v2 ที่ลักษณะการทำงานเปลี่ยนไปตามการมี swSrc อยู่
  • โดยค่าเริ่มต้น ระบบจะแคชชิ้นงานในไปป์ไลน์การคอมไพล์ Webpack ล่วงหน้า และไม่จำเป็นต้องกำหนดค่า globPatterns อีกต่อไป เหตุผลเดียวที่จะใช้ globPatterns ต่อไปคือต้องแคชเนื้อหาที่ไม่ได้รวมไว้ในบิลด์ Webpack ล่วงหน้า โดยทั่วไป เมื่อเปลี่ยนไปใช้ปลั๊กอิน v3 คุณควรเริ่มต้นด้วยการนำการกำหนดค่าที่ใช้ glob ก่อนหน้านี้ออกทั้งหมด และเพิ่มกลับเข้าไปใหม่เมื่อจำเป็นเท่านั้น

การขอความช่วยเหลือ

เราคาดว่าการย้ายข้อมูลส่วนใหญ่จะเป็นไปอย่างง่ายดาย หากคุณพบปัญหาที่ไม่ครอบคลุมอยู่ในคู่มือนี้ โปรดแจ้งให้เราทราบโดยการเปิดปัญหาบน GitHub