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

Một mô-đun Workbox chưa có nhiều nội dung trong tài liệu này là workbox-window. Đây là một tập hợp các mô-đun được dùng để chạy trong window. Mục tiêu của mô-đun này là:

  • Đơn giản hoá việc đăng ký và cập nhật worker 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 worker dịch vụ, giúp họ dễ dàng phản hồi hơn trong những thời điểm đó.
  • Để tránh các nhà phát triển mắc phải những 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 worker dịch vụ.

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

Lớp xuất mà 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 Node hoặc từ CDN trong một 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ể nhóm 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 từ 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 khỏi logic ứng dụng cốt lõi của trang web bằng cách sử dụng import động, điều 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ệp này 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". Bạn phải thực hiện bước này nếu muốn sử dụng câu lệnh import tĩnh trong trình duyệt mà không cần bước tạo bản dựng. Tất cả trình duyệt chính hỗ trợ worker 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ý trình chạy dịch vụ

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

Giao tiếp giữa window và phạm vi trình chạy dịch vụ

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

Workbox sử dụng một định dạng cụ thể cho tin nhắn 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 bằng chữ hoa, 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 biểu thị 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 bạn muốn gửi. Dữ liệu có thể là bất kỳ kiểu 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 worker dịch vụ:

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

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

Sau đó, mã sau đây vào 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);

Có 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 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.