Sử dụng plugin

Khi sử dụng Workbox, bạn nên thao tác với một yêu cầu và phản hồi khi chúng đang được tìm nạp hoặc lưu vào bộ nhớ đệm. Trình bổ trợ hộp làm việc cho phép bạn thêm các hành vi bổ sung cho trình chạy dịch vụ mà không cần nhiều mã nguyên mẫu bổ sung. Chúng có thể được đóng gói và sử dụng lại trong các dự án của riêng bạn hoặc được phát hành công khai để người khác sử dụng.

Workbox cung cấp một số plugin có sẵn cho chúng tôi và — nếu bạn là người thích sử dụng các tính năng này, bạn có thể viết các plugin tùy chỉnh phù hợp với yêu cầu của ứng dụng của mình.

Các trình bổ trợ hiện có cho Workbox

Workbox cung cấp các plugin chính thức sau đây để sử dụng trong trình chạy dịch vụ:

Các trình bổ trợ Workbox (cho dù là một trong những trình bổ trợ được liệt kê ở trên hay một trình bổ trợ tuỳ chỉnh) đều được sử dụng cùng với chiến lược Workbox bằng cách thêm một bản sao trình bổ trợ vào thuộc tính plugins của chiến lược:

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

Các phương thức dành cho trình bổ trợ tuỳ chỉnh

Trình bổ trợ Workbox cần triển khai một hoặc nhiều hàm callback. Khi bạn thêm một trình bổ trợ vào một Chiến lược, các hàm callback sẽ tự động chạy vào đúng thời điểm. Chiến lược truyền cho hàm callback của bạn thông tin liên quan đến yêu cầu và/hoặc phản hồi hiện tại, cung cấp cho trình bổ trợ của bạn ngữ cảnh cần để thực hiện hành động. Các hàm callback sau được hỗ trợ:

  • cacheWillUpdate: Được gọi trước khi Response được dùng để cập nhật bộ nhớ đệm. Trong phương thức này, phản hồi có thể thay đổi trước khi thêm vào bộ nhớ đệm, hoặc bạn có thể trả về null để tránh việc cập nhật toàn bộ bộ nhớ đệm.
  • cacheDidUpdate: Được gọi khi một mục mới được thêm vào bộ nhớ đệm hoặc nếu một mục hiện có được cập nhật. Các trình bổ trợ sử dụng phương thức này có thể hữu ích khi bạn muốn thực hiện một thao tác sau khi cập nhật bộ nhớ đệm.
  • cacheKeyWillBeUsed: Được gọi trước khi một yêu cầu được dùng làm khoá bộ nhớ đệm. Điều này xảy ra đối với cả tra cứu bộ nhớ đệm (khi mode'read') và hoạt động ghi bộ nhớ đệm (khi mode'write'). Lệnh gọi lại này rất hữu ích nếu bạn cần ghi đè hoặc chuẩn hoá URL trước khi dùng các URL này để truy cập vào bộ nhớ đệm.
  • cachedResponseWillBeUsed: Lệnh này được gọi ngay trước khi một phản hồi từ bộ nhớ đệm được sử dụng, cho phép bạn kiểm tra phản hồi đó. Tại thời điểm này, bạn có thể trả về một phản hồi khác hoặc trả về null.
  • requestWillFetch: Được gọi bất cứ khi nào có yêu cầu sắp kết nối mạng. Hữu ích khi bạn cần thay đổi Request ngay trước khi mạng vào mạng.
  • fetchDidFail: Được gọi khi yêu cầu mạng không thành công, rất có thể là do không có kết nối mạng và sẽ không kích hoạt khi trình duyệt có kết nối mạng nhưng gặp lỗi (ví dụ: 404 Not Found).
  • fetchDidSucceed: Được gọi bất cứ khi nào một yêu cầu mạng thành công, bất kể mã phản hồi HTTP là gì.
  • handlerWillStart: Được gọi trước khi logic của trình xử lý bất kỳ bắt đầu chạy. Điều này rất hữu ích nếu bạn cần đặt trạng thái ban đầu của trình xử lý. Ví dụ: nếu muốn biết trình xử lý mất bao lâu để tạo một phản hồi, bạn có thể ghi lại thời gian bắt đầu trong lệnh gọi lại này.
  • handlerWillRespond: Được gọi trước khi phương thức handle() của chiến lược trả về một phản hồi. Điều này rất hữu ích nếu bạn cần sửa đổi phản hồi trước khi trả về một RouteHandler hoặc logic tuỳ chỉnh khác.
  • handlerDidRespond: Được gọi sau khi phương thức handle() của chiến lược trả về một phản hồi. Đây là thời điểm bạn nên ghi lại mọi thông tin chi tiết về phản hồi cuối cùng (ví dụ: sau khi các trình bổ trợ khác thực hiện các thay đổi).
  • handlerDidComplete: Được gọi sau khi tất cả lời hứa hẹn kéo dài suốt thời gian hoạt động được thêm vào sự kiện từ lệnh gọi chiến lược đã xử lý xong. Điều này rất hữu ích nếu bạn cần báo cáo về bất kỳ dữ liệu nào cần phải đợi cho đến khi trình xử lý hoàn tất để tính toán các nội dung như trạng thái truy cập vào bộ nhớ đệm, độ trễ của bộ nhớ đệm, độ trễ mạng và các thông tin hữu ích khác.
  • handlerDidError: Được gọi nếu trình xử lý không thể cung cấp phản hồi hợp lệ từ bất kỳ nguồn nào. Đây là thời điểm tối ưu để cung cấp một số loại phản hồi dự phòng như một giải pháp thay thế cho việc thất bại hoàn toàn.

Tất cả các lệnh gọi lại này đều là async nên sẽ yêu cầu phải dùng await mỗi khi một sự kiện tìm nạp hoặc bộ nhớ đệm đạt đến điểm liên quan đối với lệnh gọi lại liên quan.

Nếu một trình bổ trợ đã sử dụng tất cả các lệnh gọi lại ở trên, thì đây sẽ là mã kết quả:

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

Đối tượng event có trong các lệnh gọi lại được liệt kê ở trên là sự kiện ban đầu đã kích hoạt thao tác tìm nạp hoặc lưu vào bộ nhớ đệm. Đôi khi, không có một sự kiện gốc. Vì vậy, mã của bạn nên kiểm tra xem sự kiện đó có tồn tại hay không trước khi tham chiếu.

Tất cả các lệnh gọi lại trình bổ trợ cũng được truyền một đối tượng state. Đối tượng này là duy nhất đối với một trình bổ trợ cụ thể và chiến lược mà trình bổ trợ đó gọi. Điều này có nghĩa là bạn có thể viết các trình bổ trợ trong đó một lệnh gọi lại có thể thực hiện một thao tác có điều kiện, dựa trên hoạt động của một lệnh gọi lại khác trong cùng trình bổ trợ (ví dụ: tính sự khác biệt giữa việc chạy requestWillFetch()fetchDidSucceed() hoặc fetchDidFail()).

Trình bổ trợ của bên thứ ba

Nếu bạn phát triển một trình bổ trợ và cho rằng trình bổ trợ đó được sử dụng bên ngoài dự án của mình, bạn nên phát hành trình bổ trợ đó dưới dạng một mô-đun! Dưới đây là danh sách ngắn các trình bổ trợ Workbox do cộng đồng cung cấp:

Bạn có thể tìm thêm trình bổ trợ Workbox do cộng đồng cung cấp bằng cách tìm kiếm trong kho lưu trữ của npm.

Cuối cùng, nếu bạn đã tạo một trình bổ trợ Workbox mà bạn muốn chia sẻ, hãy thêm từ khoá workbox-plugin khi xuất bản. Nếu bạn làm như vậy, hãy cho chúng tôi biết trên Twitter @WorkboxJS!