Menggunakan plugin

Saat menggunakan Workbox, Anda mungkin ingin memanipulasi permintaan dan respons saat diambil atau di-cache. Plugin Workbox memungkinkan Anda menambahkan perilaku tambahan ke pekerja layanan dengan boilerplate tambahan minimal. Model ini dapat dikemas dan digunakan kembali dalam project Anda sendiri, atau dirilis secara publik agar dapat digunakan orang lain juga.

Workbox menyediakan sejumlah plugin siap pakai yang tersedia untuk kita, dan—jika Anda adalah orang yang cerdik—Anda dapat menulis plugin kustom yang disesuaikan dengan persyaratan aplikasi Anda.

Plugin Workbox yang tersedia

Workbox menawarkan plugin resmi berikut untuk digunakan di pekerja layanan Anda:

Plugin workbox—baik plugin yang tercantum di atas maupun plugin kustom—digunakan dengan strategi Workbox dengan menambahkan instance plugin ke properti plugins strategi:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {ExpirationPlugin} from 'workbox-expiration';

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    cacheName: 'images',
    plugins: [
      new ExpirationPlugin({
        maxEntries: 60,
        maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
      }),
    ],
  })
);

Metode untuk plugin kustom

Plugin Workbox perlu menerapkan satu atau beberapa fungsi callback. Saat Anda menambahkan plugin ke Strategi, fungsi callback akan otomatis dijalankan pada waktu yang tepat. Strategi meneruskan informasi yang relevan tentang permintaan dan/atau respons saat ini ke fungsi callback Anda, sehingga plugin Anda memiliki konteks yang diperlukan untuk mengambil tindakan. Fungsi callback berikut didukung:

  • cacheWillUpdate: Dipanggil sebelum Response digunakan untuk mengupdate cache. Dalam metode ini, respons dapat diubah sebelum ditambahkan ke cache, atau Anda dapat menampilkan null untuk menghindari pembaruan cache sepenuhnya.
  • cacheDidUpdate: Dipanggil saat entri baru ditambahkan ke cache atau jika entri yang sudah ada diperbarui. Plugin yang menggunakan metode ini mungkin berguna saat Anda ingin melakukan tindakan setelah pembaruan cache.
  • cacheKeyWillBeUsed: Dipanggil sebelum permintaan digunakan sebagai kunci cache. Hal ini terjadi untuk pencarian cache (saat mode adalah 'read') dan penulisan cache (saat mode adalah 'write'). Callback ini berguna jika Anda perlu mengganti atau menormalisasi URL sebelum menggunakannya untuk mengakses cache.
  • cachedResponseWillBeUsed: Ini dipanggil tepat sebelum respons dari cache digunakan, yang memungkinkan Anda memeriksa respons tersebut. Pada saat ini, Anda dapat menampilkan respons yang berbeda, atau menampilkan null.
  • requestWillFetch: Dipanggil setiap kali permintaan akan masuk ke jaringan. Berguna saat Anda perlu mengubah Request tepat sebelum dikirim ke jaringan.
  • fetchDidFail: Dipanggil saat permintaan jaringan gagal, kemungkinan besar karena tidak adanya konektivitas jaringan, dan tidak akan diaktifkan saat browser memiliki koneksi jaringan, tetapi menerima error (misalnya, 404 Not Found).
  • fetchDidSucceed: Dipanggil setiap kali permintaan jaringan berhasil, terlepas dari kode respons HTTP.
  • handlerWillStart: Dipanggil sebelum logika pengendali mulai berjalan, yang berguna jika Anda perlu menetapkan status pengendali awal. Misalnya, jika ingin mengetahui waktu yang diperlukan pengendali untuk membuat respons, Anda dapat mencatat waktu mulai dalam callback ini.
  • handlerWillRespond: Dipanggil sebelum metode handle() strategi menampilkan respons, yang berguna jika Anda perlu mengubah respons sebelum menampilkannya ke RouteHandler atau logika kustom lainnya.
  • handlerDidRespond: Dipanggil setelah metode handle() strategi menampilkan respons. Pada saat inilah Anda mungkin perlu mencatat detail respons akhir (misalnya, setelah perubahan yang dilakukan oleh plugin lain).
  • handlerDidComplete: Dipanggil setelah semua promise masa aktif yang diperpanjang yang ditambahkan ke peristiwa dari pemanggilan strategi telah diselesaikan. Ini berguna jika Anda perlu melaporkan data apa pun yang perlu menunggu hingga pengendali selesai, untuk menghitung hal-hal seperti status cache ditemukan, latensi cache, latensi jaringan, dan informasi berguna lainnya.
  • handlerDidError: Dipanggil jika pengendali tidak dapat memberikan respons yang valid dari sumber mana pun, yang merupakan waktu optimal untuk memberikan semacam respons penggantian sebagai alternatif untuk gagal sepenuhnya.

Semua callback ini adalah async, sehingga akan memerlukan await untuk digunakan setiap kali peristiwa cache atau pengambilan mencapai titik yang relevan untuk callback yang bersangkutan.

Jika plugin menggunakan semua callback di atas, kode yang dihasilkan adalah:

const myPlugin = {
  cacheWillUpdate: async ({request, response, event, state}) => {
    // Return `response`, a different `Response` object, or `null`.
    return response;
  },
  cacheDidUpdate: async ({
    cacheName,
    request,
    oldResponse,
    newResponse,
    event,
    state,
  }) => {
    // No return expected
    // Note: `newResponse.bodyUsed` is `true` when this is called,
    // meaning the body has already been read. If you need access to
    // the body of the fresh response, use a technique like:
    // const freshResponse = await caches.match(request, {cacheName});
  },
  cacheKeyWillBeUsed: async ({request, mode, params, event, state}) => {
    // `request` is the `Request` object that would otherwise be used as the cache key.
    // `mode` is either 'read' or 'write'.
    // Return either a string, or a `Request` whose `url` property will be used as the cache key.
    // Returning the original `request` will make this a no-op.
    return request;
  },
  cachedResponseWillBeUsed: async ({
    cacheName,
    request,
    matchOptions,
    cachedResponse,
    event,
    state,
  }) => {
    // Return `cachedResponse`, a different `Response` object, or null.
    return cachedResponse;
  },
  requestWillFetch: async ({request, event, state}) => {
    // Return `request` or a different `Request` object.
    return request;
  },
  fetchDidFail: async ({originalRequest, request, error, event, state}) => {
    // No return expected.
    // Note: `originalRequest` is the browser's request, `request` is the
    // request after being passed through plugins with
    // `requestWillFetch` callbacks, and `error` is the exception that caused
    // the underlying `fetch()` to fail.
  },
  fetchDidSucceed: async ({request, response, event, state}) => {
    // Return `response` to use the network response as-is,
    // or alternatively create and return a new `Response` object.
    return response;
  },
  handlerWillStart: async ({request, event, state}) => {
    // No return expected.
    // Can set initial handler state here.
  },
  handlerWillRespond: async ({request, response, event, state}) => {
    // Return `response` or a different `Response` object.
    return response;
  },
  handlerDidRespond: async ({request, response, event, state}) => {
    // No return expected.
    // Can record final response details here.
  },
  handlerDidComplete: async ({request, response, error, event, state}) => {
    // No return expected.
    // Can report any data here.
  },
  handlerDidError: async ({request, event, error, state}) => {
    // Return a `Response` to use as a fallback, or `null`.
    return fallbackResponse;
  },
};

Objek event yang tersedia dalam callback yang tercantum di atas adalah peristiwa asli yang memicu tindakan pengambilan atau cache. Terkadang, tidak akan ada peristiwa asli, sehingga kode Anda harus memeriksa apakah peristiwa tersebut ada sebelum mereferensikannya.

Semua callback plugin juga diteruskan objek state yang bersifat unik untuk plugin tertentu dan strategi yang dipanggilnya. Artinya, Anda dapat menulis plugin dengan satu callback yang dapat secara kondisional melakukan tugas berdasarkan tindakan callback lain dalam plugin yang sama (misalnya, menghitung perbedaan antara menjalankan requestWillFetch() dan fetchDidSucceed() atau fetchDidFail()).

Plugin pihak ketiga

Jika Anda mengembangkan {i>plugin<i} dan menurut Anda plugin tersebut telah digunakan di luar proyek Anda, sebaiknya publikasikan sebagai modul. Berikut adalah daftar singkat plugin Workbox yang disediakan komunitas:

Anda mungkin dapat menemukan lebih banyak plugin Workbox yang disediakan komunitas dengan menelusuri di repositori npm.

Terakhir, jika Anda telah membuat plugin Workbox yang ingin dibagikan, tambahkan kata kunci workbox-plugin saat Anda memublikasikannya. Jika ya, beri tahu kami di Twitter @WorkboxJS.