Menggunakan Workbox tanpa precaching

Sejauh ini, dokumentasi ini telah banyak membahas pra-cache, yang sering kali membahas alat build generateSW dan injectManifest. Meskipun ada banyak alasan bagus untuk menyertakan logika pra-cache di pekerja layanan, Anda tidak perlu menggunakan pra-cache untuk menggunakan Workbox.

Mungkin project Anda hanya memerlukan caching runtime, atau mungkin Anda menginginkan cara yang lebih bersih untuk mengintegrasikan API pekerja layanan, seperti push web. Ini adalah kasus saat Anda tidak ingin menggunakan alat build Workbox, dan itulah yang dibahas dalam artikel ini.

Saat menggunakan bundler

Paketer sangat populer di lanskap pengembangan web, dan kemungkinan besar project Anda menggunakannya. Jika demikian, penting untuk diketahui bahwa Anda tidak perlu menggunakan plugin bundler (seperti workbox-webpack-plugin) jika tidak melakukan pra-cache apa pun. Anda akan memperlakukan pekerja layanan sebagai titik entri terpisah di aplikasi.

Di root direktori sumber project, Anda akan membuat pekerja layanan dan menggunakan modul Workbox apa pun yang diperlukan aplikasi Anda. Berikut adalah contoh tanpa pra-cache, yang menyiapkan strategi penyimpanan dalam cache untuk permintaan navigasi dan aset gambar dalam instance Cache terpisah:

// sw.js
import {NetworkFirst, CacheFirst} from 'workbox-strategies';
import {registerRoute, NavigationRoute, Route} from 'workbox-routing';

const navigationRoute = new NavigationRoute(new NetworkFirst({
  cacheName: 'navigations'
}));

const imageAssetRoute = new Route(({request}) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'image-assets'
}));

registerRoute(navigationRoute);
registerRoute(imageAssetRoute);

Dari sini, sekarang kita menentukan pekerja layanan ini sebagai titik masuk dalam pemaket pilihan Anda. Berikut beberapa contoh cara melakukannya di beberapa alat pembuat paket populer.

webpack

webpack menerima titik entri dalam konfigurasi entry. Ada beberapa hal yang perlu diperhatikan saat menggunakan pendekatan ini:

  1. Untuk memastikan pekerja layanan memiliki cakupan seluas mungkin, Anda sebaiknya membuat output ke root direktori output.
  2. Anda tidak ingin pekerja layanan dibuat versi, karena update pada pekerja layanan akan menghasilkan hash baru yang dapat mengakibatkan beberapa pekerja layanan di-deploy di situs Anda.

Untuk memenuhi kondisi di atas, fungsi dapat diteruskan ke output.filename yang memeriksa apakah titik entri saat ini yang sedang diproses adalah titik entri pekerja layanan. Jika tidak, file berversi akan ditulis ke tujuan normalnya.

// webpack.config.js
import process from 'process';

const isProd = process.env.NODE_ENV === 'production';

export default {
  mode: isProd ? 'production' : 'development',
  context: process.cwd(),
  entry: {
    // Service worker entry point:
    sw: './src/sw.js',
    // Application entry point:
    app: './src/index.js'
  },
  output: {
    filename: ({runtime}) => {
      // Check if the current filename is for the service worker:
      if (runtime === 'sw') {
        // Output a service worker in the root of the dist directory
        // Also, ensure the output file name doesn't have a hash in it
        return '[name].js';
      }

      // Otherwise, output files as normal
      return 'js/[name].[contenthash:8].js';
    },
    path: './dist',
    publicPath: '/',
    clean: true
  }
};

penggabungan

Rollup adalah situasi yang serupa dengan webpack, kecuali bahwa beberapa titik entri ditentukan sebagai objek konfigurasi terpisah yang diekspor dalam array:

// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';

// Plugins common to both entry points
const plugins = [
  nodeResolve(),
];

export default [
  // Application entry point
  {
    input: './src/index.js',
    output: {
      dir: './dist/js',
      format: 'esm'
    },
    plugins
  },
  // Service worker entry point
  {
    input: './src/sw.js',
    output: {
      file: './dist/sw.js',
      format: 'iife'
    },
    plugins: [
      ...plugins,
      // This @rollup/plugin-replace instance replaces process.env.NODE_ENV
      // statements in the Workbox libraries to match your current environment.
      // This changes whether logging is enabled ('development') or disabled ('production').
      replace({
        'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
      })
    ]
  }
];

esbuild

esbuild menawarkan antarmuka command line yang mudah:

npx esbuild ./src/sw.js --bundle --minify --outfile=./dist/sw.js

esbuild akan menangani penggantian process.env.NODE_ENV dengan 'development' secara default, atau 'production' jika minifikasi diaktifkan.

Tanpa bundler menggunakan workbox-sw

Project Anda bahkan mungkin tidak menggunakan pemaket. workbox-sw dapat memuat runtime Workbox untuk Anda dari CDN dalam pekerja layanan dan tanpa langkah build jika Anda mengimpornya dengan importScripts:

// sw.js

// Imports Workbox from the CDN. Note that "6.2.0" of the URL
// is the version of the Workbox runtime.
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-sw.js');

const navigationRoute = new workbox.routing.NavigationRoute(new workbox.strategies.NetworkFirst({
  cacheName: 'navigations'
}));

const imageAssetRoute = new workbox.routing.Route(({request}) => {
  return request.destination === 'image';
}, new workbox.strategies.CacheFirst({
  cacheName: 'image-assets'
}));

workbox.routing.registerRoute(navigationRoute);
workbox.routing.registerRoute(staticAssetRoute);

Jika prospek memuat runtime Workbox dari CDN tidak tampak bagus, Anda dapat menggunakan workbox-sw dengan URL lokal.

Kesimpulan

Setelah mengetahui cara menggunakan Workbox tanpa pra-cache, Anda tidak lagi terikat dengan alat build atau bundler tertentu. Ini memberi Anda fleksibilitas untuk membuat pekerja layanan hanya dengan menggunakan bit kode cache runtime Workbox yang Anda minati.