Bermigrasi dari Workbox v4 ke v5

Panduan ini berfokus pada perubahan yang dapat menyebabkan gangguan yang diperkenalkan di Workbox v5, dengan contoh perubahan yang perlu Anda lakukan 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 agar mengikuti ID paket pola + Plugin:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

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

Titik Penggantian Manifes Pracache Default

Sebelumnya, saat menggunakan salah satu alat build dalam mode "memasukkan manifes", file pekerja layanan sumber Anda akan diperiksa keberadaan precacheAndRoute([]), dengan array kosong [] tersebut digunakan sebagai placeholder untuk titik tempat manifes pracache dimasukkan.

Di Workbox v5, logika pengganti 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 akan 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, yaitu blacklist dan whitelist, telah diganti namanya menjadi denylist dan allowlist.

workbox-routing sebelumnya mendukung sebuah 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 sebelumnya di-cache, terlepas dari URL yang dibuka.

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

Langkah kedua, menghasilkan respons dengan membaca dari cache, berada di luar yang kita lihat sebagai tanggung jawab workbox-routing. Sebagai gantinya, kita melihatnya sebagai fungsi yang harus menjadi bagian dari workbox-precaching, melalui metode baru, createHandlerBoundToURL(). Metode baru ini dapat berfungsi bersama dengan class NavigationRoute yang ada di workbox-routing untuk menyelesaikan logika yang sama.

Jika Anda menggunakan opsi navigateFallback di salah satu mode "buat SW" alat build, peralihan akan terjadi secara otomatis. Jika sebelumnya Anda mengonfigurasi opsi navigateFallbackBlacklist atau navigateFallbackWhitelist, ubah opsi tersebut menjadi navigateFallbackDenylist atau navigateFallbackAllowlist.

Jika Anda menggunakan mode "injeksi manifes" atau hanya menulis sendiri pekerja layanan, dan pekerja layanan Workbox v4 memanggil registerNavigationRoute() secara langsung, Anda harus membuat perubahan pada 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 menanganinya untuk Anda.

Penghapusan makeRequest() dari strategi kotak kerja

Memanggil makeRequest() sebagian besar setara dengan memanggil handle() di salah satu class workbox-strategy. Perbedaan antara kedua metode itu sangat sedikit sehingga menjaga keduanya tidak masuk akal. Developer yang memanggil makeRequest() akan dapat beralih 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 wajib, 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 keharusan untuk mendengarkan dua sumber potensial dari 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 di-buffer secara otomatis hingga pemroses peristiwa message disiapkan. Tidak ada buffering dengan Broadcast Channel API, dan pesan yang disiarkan hanya 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 Versi 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 versi 8, update runtime ke versi yang didukung.

workbox-webpack-plugin Memerlukan webpack v4 atau Versi yang Lebih Tinggi

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

Perbaikan Opsi Alat Build

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 relevan.

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

Penghapusan generateSWString dari workbox-build

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

Perubahan Opsional

Menggunakan Impor Modul

Meskipun perubahan ini a) opsional dan b) secara teknis dimungkinkan saat menggunakan Workbox v4, perubahan terbesar yang kami antisipasi saat beralih ke v5 adalah model di mana Anda membuat pekerja layanan paket Anda sendiri dengan mengimpor modul Workbox. Pendekatan ini merupakan 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 "buat SW", perubahan ini akan terjadi secara otomatis. Semua alat tersebut akan menghasilkan paket lokal kustom dari runtime Workbox bersama dengan kode sebenarnya yang diperlukan untuk mengimplementasikan 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 (jika disetel ke false, yang merupakan default), atau disertakan inline bersama logika pekerja layanan (jika disetel ke true).

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

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

Membaca Respons yang Di-cache

Beberapa developer perlu membaca respons pra-cache langsung dari cache, bukan secara implisit menggunakannya melalui metode precacheAndRoute(). Pola umum di v4 adalah terlebih dahulu mendapatkan kunci cache khusus untuk versi resource yang di-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`);

Adopsi TypeScript

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

Contoh Migrasi

Commit ini menggambarkan adalah migrasi yang cukup terlibat, dengan komentar inline. Contoh ini menggunakan Rollup untuk menyertakan runtime Workbox kustom dalam pekerja layanan akhir, bukan memuat runtime dari CDN.

Meskipun tidak mencakup setiap perubahan yang dapat menyebabkan gangguan, berikut adalah hal sebelum dan sesudah 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 tercakup dalam panduan ini, beri tahu kami dengan membuka masalah di GitHub.