Sử dụng cửa sổ hộp làm việc

Một mô-đun Workbox chưa được đề cập nhiều trong tài liệu này là workbox-window, đây là một tập hợp các mô-đun dự định chạy trong window. Mục tiêu của học phần này là:

  • Để đơn giản hoá việc đăng ký và cập nhật trình chạy dịch vụ bằng cách giúp nhà phát triển xác định những thời điểm quan trọng trong vòng đời của trình chạy dịch vụ, giúp nhà phát triển phản hồi dễ dàng hơn vào những thời điểm đó.
  • Để tránh các nhà phát triển mắc lỗi phổ biến, chẳng hạn như đăng ký một trình chạy dịch vụ không đúng phạm vi.
  • Để đơn giản hoá việc nhắn tin giữa windowphạm vi của trình chạy dịch vụ.

Đang nhập và sử dụng workbox-window

Loại tệp xuất bạn sẽ sử dụng thường xuyên nhất từ workbox-window là lớp Workbox. Bạn có thể nhập lớp này trong Nút hoặc từ CDN trong trang web.

Tạo gói cục bộ

Nếu chuỗi công cụ của bạn bao gồm một trình gói như webpack hoặc Rollup, thì bạn có thể gói workbox-window cục bộ.

Trước tiên, hãy cài đặt workbox-window dưới dạng phần phụ thuộc phát hành chính thức của ứng dụng:

npm install workbox-window --save

Sau đó, trong JavaScript của ứng dụng, bạn có thể import lớp Workbox qua workbox-window:

<script type="module">
import {Workbox} from 'workbox-window';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  wb.register();
}
</script>

Mặc dù workbox-window khá nhỏ, nhưng bạn có thể tách nó khỏi logic ứng dụng cốt lõi của trang web bằng cách sử dụng import động. Thao tác này có thể làm giảm kích thước gói chính trên trang của bạn:

<script type="module">
if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}
</script>

Sử dụng CDN

Mặc dù không phải là phương pháp được đề xuất, nhưng cách dễ dàng hơn để sử dụng workbox-window là nhập từ CDN:

<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    wb.register();
  }
</script>

Bạn sẽ lưu ý rằng phần tử <script> trong ví dụ trên sử dụng thuộc tính type="module". Đây là yêu cầu bắt buộc nếu bạn muốn sử dụng câu lệnh import tĩnh trong trình duyệt mà không cần thực hiện bước tạo bản dựng. Tất cả các trình duyệt chính có hỗ trợ trình chạy dịch vụ cũng hỗ trợ các mô-đun JavaScript, vì vậy bạn có thể phân phát mã này cho bất kỳ trình duyệt nào, vì các trình duyệt cũ sẽ bỏ qua các phần tử <script> có giá trị thuộc tính type"module".

Đăng ký một trình chạy dịch vụ

Việc đăng ký một trình chạy dịch vụ với workbox-window được hoàn tất bằng phương thức register của lớp Workbox như sau:

import {Workbox} from 'workbox-window';

const wb = new Workbox('/sw.js');
wb.register();

Có vẻ như việc này giống với việc tự đăng ký một trình chạy dịch vụ bằng navigator.serviceWorker.register. Tuy nhiên, Workbox.register sẽ chờ cho đến khi xảy ra sự kiện window load trước khi đăng ký trình chạy dịch vụ. Điều này là cần thiết trong các trường hợp có liên quan đến tính năng lưu trước vào bộ nhớ đệm để có thể tránh được tranh chấp băng thông có thể làm chậm quá trình khởi động trang.

Trao đổi thông tin giữa window và phạm vi của trình chạy dịch vụ

Trình chạy dịch vụ có phạm vi riêng tách biệt với window và chỉ có quyền truy cập vào một tập hợp con các API có trong window. Tuy nhiên, bạn có thể giao tiếp giữa window và trình chạy dịch vụ. workbox-window cho phép giao tiếp dễ dàng hơn giữa hai phạm vi bằng phương thức messageSW của mô-đun workbox-window.

Workbox sử dụng định dạng cụ thể cho thông báo và là một đối tượng có các thuộc tính sau:

  • type là một chuỗi duy nhất bắt buộc để xác định thông báo. Định dạng phải được viết hoa và có dấu gạch dưới phân tách các từ (ví dụ: CACHE_URLS).
  • meta là một chuỗi không bắt buộc đại diện cho tên của gói Workbox gửi thông báo và thường bị bỏ qua.
  • payload là một tham số không bắt buộc đại diện cho dữ liệu mà bạn muốn gửi. Đó có thể là bất kỳ loại dữ liệu nào.

Dưới đây là ví dụ về cách hoạt động của messageSW, bắt đầu bằng mã trong trình chạy dịch vụ của bạn:

// sw.js
const SW_VERSION = '1.0.0';

self.addEventListener('message', (event) => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

Và tiếp theo là mã sau đây trong trang web của bạn:

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

Trong nhiều trường hợp, việc giao tiếp giữa một trình chạy dịch vụ và window có thể hữu ích, chẳng hạn như thông báo cho người dùng khi có bản cập nhật của trình chạy dịch vụ. Công thức đó dựa vào một phương thức trợ giúp đặc biệt cho self.skipWaiting có tên là messageSkipWaiting. Phương thức này sẽ gửi một thông báo có giá trị typeSKIP_WAITING.