Sử dụng Workbox mà không cần lưu trước vào bộ nhớ đệm

Cho đến nay, tài liệu này chủ yếu tập trung vào việc lưu vào bộ nhớ đệm, thường là đề cập đến các công cụ bản dựng generateSWinjectManifest. Mặc dù có nhiều lý do hợp lý để đưa logic lưu trước vào bộ nhớ đệm trong trình chạy dịch vụ, nhưng bạn không nhất thiết phải dùng tính năng lưu vào bộ nhớ đệm để sử dụng Workbox.

Có lẽ dự án của bạn chỉ cần lưu vào bộ nhớ đệm trong thời gian chạy hoặc có thể bạn muốn có một cách gọn gàng hơn để tích hợp các API trình chạy dịch vụ, chẳng hạn như đẩy web. Đây là những trường hợp bạn không muốn sử dụng các công cụ xây dựng của Workbox và đó là nội dung được đề cập trong bài viết này.

Khi sử dụng trình phân gói

Trong lĩnh vực phát triển web, định dạng Bundle là một phần rất quan trọng, vì vậy, có khả năng dự án của bạn cũng đang sử dụng gói này. Trong trường hợp này, bạn cần lưu ý là bạn không cần sử dụng trình bổ trợ trình gói (chẳng hạn như workbox-webpack-plugin) nếu hiện không lưu trước bất cứ thứ gì. Bạn sẽ coi trình chạy dịch vụ là một điểm truy cập riêng biệt trong ứng dụng của mình.

Ở gốc thư mục nguồn của dự án, bạn sẽ tạo một trình chạy dịch vụ và sử dụng bất kỳ mô-đun Workbox nào mà ứng dụng của bạn yêu cầu. Sau đây là một ví dụ mà không cần lưu vào bộ nhớ đệm, giúp thiết lập các chiến lược lưu vào bộ nhớ đệm cho các yêu cầu điều hướng và thành phần hình ảnh trong các thực thể Cache riêng biệt:

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

Tại đây, bạn cần chỉ định trình chạy dịch vụ này làm điểm truy cập trong trình đóng gói mà bạn chọn. Dưới đây là một vài ví dụ về cách thực hiện việc đó trong một số trình gói phổ biến.

gói web

webpack chấp nhận các điểm truy cập trong cấu hình entry. Có một vài điều bạn cần lưu ý khi sử dụng phương pháp này:

  1. Để đảm bảo trình chạy dịch vụ có phạm vi rộng nhất có thể, bạn nên đưa trình chạy này vào thư mục gốc của thư mục đầu ra.
  2. Bạn không nên tạo phiên bản cho trình chạy dịch vụ, vì các bản cập nhật trình chạy dịch vụ này sẽ tạo ra các hàm băm mới. Điều này có thể khiến nhiều trình chạy dịch vụ được triển khai trên trang web của bạn.

Để đáp ứng các điều kiện trên, bạn có thể truyền một hàm đến output.filename để kiểm tra xem điểm truy cập hiện tại đang được xử lý có phải là điểm truy cập của trình chạy dịch vụ hay không. Nếu không, các tệp được tạo phiên bản sẽ được ghi vào đích đến thông thường.

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

thông tin tổng hợp

Trường hợp Rollup tương tự như webpack, ngoại trừ việc nhiều điểm truy cập được chỉ định làm đối tượng cấu hình riêng biệt được xuất trong một mảng:

// 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')
      })
    ]
  }
];

tạo bản dựng

esbuild cung cấp giao diện dòng lệnh đơn giản:

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

esbuild sẽ đảm nhiệm việc thay thế process.env.góp_ENV bằng thuộc tính "development" (phát triển) theo mặc định hoặc "product" (bản chính thức) nếu bật tính năng thu nhỏ.

Không có trình đóng gói bằng cách sử dụng workbox-sw

Dự án của bạn thậm chí không thể sử dụng trình đóng gói. workbox-sw có thể tải thời gian chạy Workbox cho bạn từ CDN trong dịch vụ worker mà không cần thực hiện bước tạo nếu bạn nhập bằng 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);

Nếu khả năng tải thời gian chạy Workbox từ CDN có vẻ không hiệu quả, bạn có thể sử dụng workbox-sw với URL cục bộ.

Kết luận

Giờ đây, bạn đã biết cách sử dụng Workbox mà không cần lưu trước vào bộ nhớ đệm, bạn không còn bị ràng buộc với một trình đóng gói hay công cụ bản dựng cụ thể nữa. Nhờ đó, bạn có thể linh hoạt trong việc tạo thủ công một trình chạy dịch vụ chỉ bằng các bit của mã lưu vào bộ nhớ đệm trong thời gian chạy của Workbox mà bạn quan tâm.