Hướng dẫn này tập trung vào việc thay đổi có thể gây lỗi được giới thiệu trong Workbox phiên bản 5, với các ví dụ về những thay đổi bạn cần thực hiện khi nâng cấp từ Workbox phiên bản 4.
Thay đổi có thể gây lỗi
Đã đổi tên lớp trình bổ trợ
Một số gói Workbox phiên bản 4 bao gồm các lớp có tên Plugin
. Trong phiên bản 5, các lớp đó đã được đổi tên để tuân theo giá trị nhận dạng gói mẫu + Plugin
:
BackgroundSyncPlugin
BroadcastUpdatePlugin
CacheableResponsePlugin
ExpirationPlugin
RangeRequestsPlugin
Việc đổi tên này sẽ áp dụng cho dù bạn đang sử dụng các lớp thông qua tính năng nhập mô-đun hay thông qua không gian tên workbox.*
.
Điểm thay thế tệp kê khai bộ nhớ đệm trước mặc định
Trước đây, khi sử dụng một trong các công cụ xây dựng trong tính năng "chèn tệp kê khai" , tệp trình chạy dịch vụ nguồn của bạn đã được kiểm tra xem có precacheAndRoute([])
hay không, với mảng trống []
đó được dùng làm phần giữ chỗ cho thời điểm mà tệp kê khai bộ nhớ đệm trước được đưa vào.
Trong Workbox phiên bản 5, logic thay thế đã thay đổi và giờ đây, self.__WB_MANIFEST
được dùng làm điểm chèn theo mặc định.
// v4:
precacheAndRoute([]);
// v5:
precacheAndRoute(self.__WB_MANIFEST);
Như đã trình bày trong cuộc thảo luận này, chúng tôi tin rằng thay đổi này sẽ mang đến trải nghiệm đơn giản hơn, đồng thời cho phép các nhà phát triển có nhiều quyền kiểm soát hơn đối với cách sử dụng tệp kê khai được chèn trong mã trình chạy dịch vụ tuỳ chỉnh. Nếu cần, bạn có thể thay đổi chuỗi thay thế này thông qua phương án cấu hình injectionPoint
.
Thay đổi tuyến đường điều hướng
2 tuỳ chọn trước đây được hỗ trợ cho tuyến đường điều hướng là blacklist
và whitelist
đã được đổi tên thành denylist
và allowlist
.
workbox-routing
trước đây đã hỗ trợ một phương thức, registerNavigationRoute()
. Về sau, phương thức này thực hiện 2 việc:
- Đã phát hiện xem một sự kiện
fetch
nhất định cómode
là'navigate'
hay không. - Nếu có, hãy phản hồi yêu cầu đó bằng nội dung của một URL được mã hoá cứng và lưu vào bộ nhớ đệm trước đó, bất kể URL đang được điều hướng đến.
Đây là một mẫu phổ biến để sử dụng khi triển khai cấu trúc Giao diện ứng dụng.
Bước thứ hai, tạo phản hồi bằng cách đọc từ bộ nhớ đệm, nằm ngoài trách nhiệm của workbox-routing
. Thay vào đó, chúng ta xem đó là chức năng cần có trong workbox-precaching
, thông qua một phương thức mới là createHandlerBoundToURL()
. Phương thức mới này có thể hoạt động song song với lớp NavigationRoute
hiện có trong workbox-routing
để thực hiện cùng một logic.
Nếu bạn đang dùng tuỳ chọn navigateFallback
trong phần "tạo SW" của công cụ xây dựng thì quá trình chuyển sẽ diễn ra tự động. Nếu trước đó bạn đã định cấu hình tuỳ chọn navigateFallbackBlacklist
hoặc navigateFallbackWhitelist
, hãy thay đổi các tuỳ chọn đó thành navigateFallbackDenylist
hoặc navigateFallbackAllowlist
tương ứng.
Nếu đang sử dụng chế độ "chèn tệp kê khai" hoặc chỉ tự viết trình chạy dịch vụ và trình chạy dịch vụ Workbox phiên bản 4 gọi trực tiếp registerNavigationRoute()
, thì bạn sẽ phải thay đổi mã để có được hành vi tương đương.
// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';
const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
whitelist: [...],
blacklist: [...],
});
// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [...],
denylist: [...],
});
registerRoute(navigationRoute);
Bạn không cần gọi getCacheKeyForURL()
nữa vì createHandlerBoundToURL()
sẽ xử lý việc đó cho bạn.
Xoá makeRequest() khỏi chiến lược hộp công việc
Việc gọi makeRequest()
gần như tương đương với việc gọi handle()
trên một trong các lớp workbox-strategy
. Sự khác biệt giữa hai phương thức này quá nhỏ nên việc giữ cả hai phương thức là không hợp lý. Nhà phát triển đã gọi makeRequest()
có thể chuyển sang sử dụng handle()
mà không cần thay đổi gì thêm:
// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});
// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});
Trong phiên bản 5, handle()
coi request
là một tham số bắt buộc và sẽ không quay lại sử dụng event.request
. Hãy đảm bảo bạn truyền một yêu cầu hợp lệ khi gọi handle()
.
workbox-broadcast-update Luôn sử dụng postMessage()
Trong phiên bản 4, thư viện workbox-broadcast-update
sẽ mặc định sử dụng Broadcast Channel API để gửi thông báo khi được hỗ trợ và chỉ sử dụng lại postMessage()
khi Broadcast Channel không được hỗ trợ.
Chúng tôi nhận thấy việc phải nghe hai nguồn tin nhắn đến tiềm năng khiến việc viết mã phía máy khách trở nên quá phức tạp. Ngoài ra, trên một số trình duyệt, các lệnh gọi postMessage()
từ worker dịch vụ được gửi đến các trang ứng dụng sẽ tự động được lưu vào bộ đệm cho đến khi bạn thiết lập trình nghe sự kiện message
. Không có bộ đệm với Broadcast Channel API và thông báo được truyền tin sẽ bị loại bỏ nếu được gửi trước khi trang ứng dụng sẵn sàng nhận thông báo.
Vì những lý do đó, chúng tôi đã thay đổi workbox-broadcast-update
để luôn sử dụng postMessage()
trong phiên bản 5. Thông báo được gửi từng thông báo đến tất cả các trang máy khách trong phạm vi của trình chạy dịch vụ hiện tại.
Để phù hợp với hành vi mới này, bạn có thể xoá mọi đoạn mã bạn có trong các trang ứng dụng đã tạo thực thể BroadcastChannel
, và thay vào đó, hãy thiết lập trình nghe sự kiện message
trên navigator.serviceWorker
:
// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
});
// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
}
});
Người dùng workbox-window
không cần thực hiện bất kỳ thay đổi nào vì logic nội bộ của ứng dụng đã được cập nhật để theo dõi các lệnh gọi postMessage()
.
Công cụ xây dựng yêu cầu Node.js phiên bản 8 trở lên
Chúng tôi không còn hỗ trợ các phiên bản Node.js trước phiên bản 8 cho workbox-webpack-plugin
, workbox-build
hoặc workbox-cli
. Nếu bạn đang chạy phiên bản Node.js trước phiên bản 8, hãy cập nhật thời gian chạy lên phiên bản được hỗ trợ.
workbox-webpack-plugin Yêu cầu webpack phiên bản 4 trở lên
Nếu bạn đang sử dụng workbox-webpack-plugin
, hãy cập nhật chế độ thiết lập webpack để sử dụng ít nhất là webpack v4.
Cải tiến tuỳ chọn công cụ bản dựng
Một số thông số cấu hình workbox-build
, workbox-cli
và workbox-webpack-plugin
không còn được hỗ trợ nữa. Ví dụ: generateSW
sẽ luôn tạo một gói thời gian chạy Workbox cục bộ cho bạn, vì vậy, tuỳ chọn importWorkboxFrom
không còn phù hợp nữa.
Tham khảo tài liệu của công cụ có liên quan để biết danh sách các tuỳ chọn được hỗ trợ.
Xoá generateSWString khỏi bản dựng hộp công việc
Chế độ generateSWString
đã bị xoá khỏi workbox-build
. Chúng tôi dự kiến tác động của việc này sẽ ở mức tối thiểu, vì workbox-webpack-plugin
chủ yếu sử dụng nội bộ.
Các thay đổi không bắt buộc
Sử dụng tính năng nhập mô-đun
Mặc dù thay đổi này là a) không bắt buộc và b) về mặt kỹ thuật là có thể thực hiện khi sử dụng Workbox v4, thay đổi lớn nhất mà chúng tôi dự đoán khi chuyển sang v5 là mô hình trong đó bạn tạo trình chạy dịch vụ đi kèm của riêng mình bằng cách nhập các mô-đun của Workbox. Phương pháp này là giải pháp thay thế cho việc gọi importScripts('/path/to/workbox-sw.js')
ở đầu trình chạy dịch vụ và sử dụng Workbox thông qua không gian tên workbox.*
.
Nếu bạn đang sử dụng một trong các công cụ xây dựng (workbox-webpack-plugin
, workbox-build
, workbox-cli
) ở chế độ "tạo SW", thì thay đổi này sẽ tự động diễn ra. Tất cả những công cụ đó sẽ tạo ra một gói tuỳ chỉnh cục bộ của thời gian chạy Workbox cùng với mã thực tế cần thiết để triển khai logic của trình chạy dịch vụ. Trong trường hợp này, không còn phần phụ thuộc nào trên workbox-sw
hoặc bản sao CDN của Workbox. Tuỳ thuộc vào giá trị của cấu hình inlineWorkboxRuntime
, thời gian chạy Workbox sẽ được chia thành một tệp riêng biệt cần được triển khai cùng với worker dịch vụ (khi được đặt thành false
, là giá trị mặc định) hoặc được đưa vào cùng dòng với logic worker dịch vụ (khi được đặt thành true
).
Nếu đang sử dụng các công cụ xây dựng ở chế độ "chèn tệp kê khai" hoặc nếu không sử dụng công cụ xây dựng của Workbox, bạn có thể tìm hiểu thêm về cách tạo gói thời gian chạy Workbox của riêng mình trong hướng dẫn Sử dụng trình tạo gói (webpack/Rollup) với Workbox hiện có.
Tài liệu và ví dụ cho phiên bản 5 được viết giả định cú pháp nhập mô-đun, mặc dù không gian tên workbox.*
sẽ tiếp tục được hỗ trợ trong Workbox phiên bản 5.
Đọc phản hồi được lưu vào bộ nhớ đệm trước
Một số nhà phát triển cần đọc trực tiếp các phản hồi được lưu vào bộ nhớ đệm từ bộ nhớ đệm, thay vì sử dụng ngầm các phản hồi đó thông qua phương thức precacheAndRoute()
. Một mẫu hình phổ biến trong phiên bản 4 là lấy khoá bộ nhớ đệm dành riêng cho phiên bản hiện tại của tài nguyên được lưu trước trong bộ nhớ đệm, rồi truyền khoá đó cùng với tên bộ nhớ đệm của bộ nhớ đệm trước vào caches.match()
để lấy Response
.
Để đơn giản hoá quy trình này, workbox-precaching
trong phiên bản 5 hỗ trợ một phương thức mới, tương đương là matchPrecache()
:
// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';
const cachedResponse = await caches.match(
getCacheKeyForURL(`/somethingPrecached`),
{
cacheName: cacheNames.precache,
}
);
// v5:
import {matchPrecache} from 'workbox-precaching';
const cachedResponse = await matchPrecache(`/somethingPrecached`);
Sử dụng TypeScript
Trong phiên bản 5, các thư viện thời gian chạy Workbox được viết bằng TypeScript. Mặc dù chúng tôi sẽ tiếp tục phát hành các mô-đun và gói JavaScript đã biên dịch để phục vụ những nhà phát triển chưa sử dụng TypeScript, nhưng nếu đang sử dụng TypeScript, bạn sẽ được hưởng lợi từ thông tin loại chính xác, luôn cập nhật trực tiếp từ dự án Workbox.
Ví dụ về quá trình di chuyển
Lần thay đổi này minh hoạ một quá trình di chuyển khá phức tạp, với bình luận cùng dòng. Công cụ này sử dụng Rollup để đưa thời gian chạy Workbox tuỳ chỉnh vào worker dịch vụ cuối cùng thay vì tải thời gian chạy từ CDN.
Mặc dù bài viết này không bao gồm mọi thay đổi có thể gây lỗi, nhưng sau đây là trước và sau khi nâng cấp một tệp trình chạy dịch vụ từ phiên bản 4 lên phiên bản 5, bao gồm cả việc chuyển sang TypeScript.
Nhận Trợ giúp
Chúng tôi dự đoán rằng hầu hết các quá trình di chuyển sẽ đơn giản. Nếu bạn gặp phải vấn đề không được đề cập trong hướng dẫn này, hãy cho chúng tôi biết bằng cách mở một vấn đề trên GitHub.