Bermigrasi dari Workbox v4 ke v5

Panduan ini berfokus pada perubahan yang menyebabkan error yang diperkenalkan di Workbox v5, dengan contoh perubahan yang perlu Anda buat saat mengupgrade dari Workbox v4.

Perubahan yang Dapat Menyebabkan Gangguan

Nama Class Plugin Diganti

Sejumlah paket Workbox v4 menyertakan class bernama Plugin. Di v5, class tersebut telah diganti namanya untuk mengikuti pola ID paket + Plugin:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

Penggantian nama ini berlaku baik Anda menggunakan class melalui impor modul atau melalui namespace workbox.*.

Titik Penggantian Manifes Pra-cache Default

Sebelumnya, saat menggunakan salah satu alat build dalam mode "inject manifest", file service worker sumber Anda diperiksa untuk mengetahui keberadaan precacheAndRoute([]), dengan array kosong [] tersebut digunakan sebagai placeholder untuk titik saat manifes pra-cache dimasukkan.

Di Workbox v5, logika penggantian telah berubah, dan sekarang self.__WB_MANIFEST digunakan secara default sebagai titik injeksi.

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

Seperti yang diuraikan dalam diskusi ini, kami yakin perubahan ini memberikan pengalaman yang lebih sederhana, sekaligus memberi developer lebih banyak kontrol atas cara manifes yang dimasukkan digunakan dalam kode pekerja layanan kustom. Jika perlu, Anda dapat mengubah string pengganti ini melalui opsi konfigurasi injectionPoint.

Dua opsi yang sebelumnya didukung untuk rute navigasi, blacklist dan whitelist, telah diganti namanya menjadi denylist dan allowlist.

workbox-routing sebelumnya mendukung metode, registerNavigationRoute(), yang, di balik layar, melakukan dua hal:

  1. Mendeteksi apakah peristiwa fetch tertentu memiliki mode 'navigate' atau tidak.
  2. Jika ya, respons permintaan tersebut menggunakan konten URL hardcode yang di-cache sebelumnya, terlepas dari URL yang dituju.

Ini adalah pola umum yang digunakan saat menerapkan arsitektur App Shell.

Langkah kedua, membuat respons dengan membaca dari cache, berada di luar apa yang kita lihat sebagai tanggung jawab workbox-routing. Sebaliknya, kita melihatnya sebagai fungsi yang harus menjadi bagian dari workbox-precaching, melalui metode baru, createHandlerBoundToURL(). Metode baru ini dapat bekerja sama dengan class NavigationRoute yang ada di workbox-routing untuk mencapai logika yang sama.

Jika Anda menggunakan opsi navigateFallback di salah satu mode "generate SW" alat build, pengalihan akan terjadi secara otomatis. Jika sebelumnya Anda telah mengonfigurasi opsi navigateFallbackBlacklist atau navigateFallbackWhitelist, ubah masing-masing menjadi navigateFallbackDenylist atau navigateFallbackAllowlist.

Jika Anda menggunakan "masukkan manifes" atau hanya menulis pekerja layanan sendiri, dan pekerja layanan Workbox v4 memanggil registerNavigationRoute() secara langsung, Anda harus mengubah kode untuk mendapatkan perilaku yang setara.

// 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);

Anda tidak perlu lagi memanggil getCacheKeyForURL(), karena createHandlerBoundToURL() akan melakukannya untuk Anda.

Penghapusan makeRequest() dari strategi workbox

Memanggil makeRequest() sebagian besar setara dengan memanggil handle() di salah satu class workbox-strategy. Perbedaan antara kedua metode itu sangat sedikit sehingga menempatkan keduanya tidak masuk akal. Developer yang memanggil makeRequest() harus dapat beralih untuk menggunakan handle() tanpa perubahan lebih lanjut:

// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});

// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});

Di v5, handle() memperlakukan request sebagai parameter yang diperlukan, dan tidak akan kembali menggunakan event.request. Pastikan Anda meneruskan permintaan yang valid saat memanggil handle().

workbox-broadcast-update Selalu Menggunakan postMessage()

Di v4, library workbox-broadcast-update secara default akan menggunakan Broadcast Channel API untuk mengirim pesan saat didukung, dan kembali menggunakan postMessage() hanya jika Saluran Siaran tidak didukung.

Kami menyadari bahwa harus memproses dua sumber potensial pesan masuk membuat penulisan kode sisi klien menjadi terlalu rumit. Selain itu, di beberapa browser, panggilan postMessage() dari pekerja layanan yang dikirim ke halaman klien akan otomatis di-buffer hingga pemroses peristiwa message disiapkan. Tidak ada buffering dengan Broadcast Channel API, dan pesan yang disiarkan akan dihapus jika dikirim sebelum halaman klien siap menerimanya.

Karena alasan tersebut, kami telah mengubah workbox-broadcast-update agar selalu menggunakan postMessage() di v5. Pesan dikirim satu per satu ke semua halaman klien dalam cakupan pekerja layanan saat ini.

Untuk mengakomodasi perilaku baru ini, Anda dapat menghapus kode apa pun yang Anda miliki di halaman klien yang membuat instance BroadcastChannel, dan sebagai gantinya, siapkan pemroses peristiwa message di 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 ...
  }
});

Pengguna workbox-window tidak perlu melakukan perubahan apa pun, karena logika internalnya telah diperbarui untuk memproses panggilan postMessage().

Build Tools Memerlukan Node.js v8 atau yang Lebih Tinggi

Versi Node.js sebelum v8 tidak lagi didukung untuk workbox-webpack-plugin, workbox-build, atau workbox-cli. Jika Anda menjalankan versi Node.js sebelum 8, update runtime ke versi yang didukung.

workbox-webpack-plugin Memerlukan webpack v4 atau yang lebih tinggi

Jika Anda menggunakan workbox-webpack-plugin, perbarui penyiapan webpack untuk menggunakan setidaknya webpack v4.

Perbaikan Opsi Build Alat

Sejumlah parameter konfigurasi workbox-build, workbox-cli, dan workbox-webpack-plugin tidak lagi didukung. Misalnya, generateSW akan selalu membuat paket runtime Workbox lokal untuk Anda, sehingga opsi importWorkboxFrom tidak lagi cocok.

Lihat dokumentasi alat yang relevan untuk mengetahui daftar opsi yang didukung.

Penghapusan generateSWString dari workbox-build

Mode generateSWString telah dihapus dari workbox-build. Kami memperkirakan dampaknya akan minimal, karena utamanya digunakan secara internal oleh workbox-webpack-plugin.

Perubahan Opsional

Menggunakan Impor Modul

Meskipun perubahan ini a) opsional dan b) secara teknis dapat dilakukan saat menggunakan Workbox v4, perubahan terbesar yang kami antisipasi saat beralih ke v5 adalah model tempat Anda membuat pekerja layanan yang dipaketkan sendiri dengan mengimpor modul Workbox. Pendekatan ini adalah alternatif untuk memanggil importScripts('/path/to/workbox-sw.js') di bagian atas pekerja layanan Anda, dan menggunakan Workbox melalui namespace workbox.*.

Jika Anda menggunakan salah satu alat build (workbox-webpack-plugin, workbox-build, workbox-cli) dalam mode "generate SW", perubahan ini akan terjadi secara otomatis. Semua alat tersebut akan menghasilkan paket kustom lokal runtime Workbox bersama dengan kode sebenarnya yang diperlukan untuk menerapkan logika pekerja layanan Anda. Dalam skenario ini, tidak ada lagi dependensi pada workbox-sw atau salinan CDN Workbox. Bergantung pada nilai konfigurasi inlineWorkboxRuntime Anda, runtime Workbox akan dibagi menjadi file terpisah yang harus di-deploy bersama pekerja layanan Anda (jika ditetapkan ke false, yang merupakan setelan default), atau disertakan secara inline bersama dengan logika pekerja layanan (jika ditetapkan ke true).

Jika menggunakan alat build dalam mode "inject manifest", atau jika tidak menggunakan alat build Workbox sama sekali, Anda dapat mempelajari lebih lanjut cara membuat paket runtime Workbox Anda sendiri di panduan Menggunakan Bundler (webpack/Rollup) dengan Workbox yang ada.

Dokumentasi dan contoh untuk v5 ditulis dengan asumsi modul mengimpor sintaksis, meskipun namespace workbox.* akan terus didukung di Workbox v5.

Membaca Respons yang Di-pra-cache

Beberapa developer perlu membaca respons yang telah di-pra-cache langsung dari cache, daripada menggunakannya secara implisit melalui metode precacheAndRoute(). Pola umum di v4 adalah terlebih dahulu mendapatkan kunci cache khusus untuk versi resource yang di-pra-cache saat ini, lalu meneruskan kunci tersebut bersama dengan nama cache precache ke caches.match() untuk mendapatkan Response.

Untuk menyederhanakan proses ini, workbox-precaching di v5 mendukung metode baru yang setara, 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`);

Pengadopsian TypeScript

Di v5, library runtime Workbox ditulis dalam TypeScript. Meskipun kami akan terus memublikasikan modul dan paket JavaScript yang ditranspilasi untuk mengakomodasi developer yang belum menggunakan TypeScript, jika Anda menggunakan TypeScript, Anda akan mendapatkan manfaat dari jenis informasi yang akurat dan selalu terbaru langsung dari project Workbox.

Contoh Migrasi

Commit ini menunjukkan migrasi yang cukup rumit, dengan komentar inline. Menggunakan Rollup untuk menyertakan runtime Workbox khusus di pekerja layanan akhir, bukan memuat runtime dari CDN.

Meskipun tidak mencakup setiap perubahan yang menyebabkan error, berikut adalah sebelum dan setelah mengupgrade satu file pekerja layanan dari v4 ke v5, termasuk peralihan ke TypeScript.

Mendapatkan Bantuan

Kami memperkirakan sebagian besar migrasi akan mudah dilakukan. Jika Anda mengalami masalah yang tidak dibahas dalam panduan ini, beri tahu kami dengan membuka masalah di GitHub.