Hướng dẫn này tập trung vào những thay đổi có thể gây lỗi trong Workbox phiên bản 6, kèm theo 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 5.
Thay đổi có thể gây lỗi
workbox-core
Phương thức skipWaiting() trong workbox-core sẽ không thêm trình xử lý install nữa và tương đương với việc chỉ gọi self.skipWaiting().
Từ giờ trở đi, hãy sử dụng self.skipWaiting() vì skipWaiting() có thể sẽ bị xoá trong Workbox phiên bản 7.
workbox-precaching
- Bạn không thể dùng tài liệu HTML khác nguồn gốc cho các URL tương ứng với lệnh chuyển hướng HTTP để đáp ứng yêu cầu điều hướng bằng
workbox-precachingnữa. Trường hợp này thường không phổ biến. - Tham số truy vấn URL
fbclidhiện bịworkbox-precachingbỏ qua khi tra cứu phản hồi được lưu trước vào bộ nhớ đệm cho một yêu cầu nhất định. - Hàm khởi tạo
PrecacheControllerhiện lấy một đối tượng có các thuộc tính cụ thể làm tham số, thay vì một chuỗi. Đối tượng này hỗ trợ các thuộc tính sau:cacheName(phục vụ cùng mục đích với chuỗi được truyền vào hàm khởi tạo trong phiên bản 5),plugins(thay thế phương thứcaddPlugins()trong phiên bản 5) vàfallbackToNetwork(thay thế tuỳ chọn tương tự được truyền đếncreateHandler()và `createHandlerBoundToURL() trong phiên bản 5). - Giờ đây, các phương thức
install()vàactivate()củaPrecacheControllerchỉ nhận đúng một tham số, tham số này phải được đặt thànhInstallEventhoặcActivateEventtương ứng. - Phương thức
addRoute()đã bị xoá khỏiPrecacheController. Thay vào đó, bạn có thể sử dụng lớpPrecacheRoutemới để tạo một tuyến đường mà sau đó bạn có thể đăng ký. - Phương thức
precacheAndRoute()đã bị xoá khỏiPrecacheController. (Phương thức này vẫn tồn tại dưới dạng phương thức trợ giúp tĩnh được mô-đunworkbox-precachingxuất.) Lớp này đã bị xoá vì bạn có thể sử dụngPrecacheRoute. - Phương thức
createMatchCalback()đã bị xoá khỏiPrecacheController. Bạn có thể sử dụngPrecacheRoutemới. - Phương thức
createHandler()đã bị xoá khỏiPrecacheController. Thay vào đó, bạn có thể sử dụng thuộc tínhstrategycủa đối tượngPrecacheControllerđể xử lý các yêu cầu. - Lệnh xuất tĩnh
createHandler()đã bị xoá khỏi mô-đunworkbox-precaching. Thay vào đó, nhà phát triển nên tạo một thực thểPrecacheControllervà sử dụng thuộc tínhstrategycủa thực thể đó. - Tuyến đường đã đăng ký với
precacheAndRoute()hiện là một tuyến đường "thực" sử dụng lớpRoutercủaworkbox-routingtrong phần nâng cao. Điều này có thể dẫn đến thứ tự đánh giá khác nhau cho các tuyến đường nếu bạn xen kẽ các lệnh gọi đếnregisterRoute()vàprecacheAndRoute().
workbox-routing
Phương thức setDefaultHandler() hiện nhận một tham số thứ hai không bắt buộc tương ứng với phương thức HTTP mà phương thức này áp dụng, mặc định là 'GET'.
- Nếu bạn sử dụng
setDefaultHandler()và tất cả yêu cầu của bạn đều làGET, thì bạn không cần thực hiện thay đổi nào. - Nếu bạn có yêu cầu nào không phải là
GET(POST,PUT, v.v.),setDefaultHandler()sẽ không còn khiến các yêu cầu đó khớp nữa.
Cấu hình bản dựng
Tuỳ chọn mode cho chế độ getManifest và injectManifest trong workbox-build và workbox-cli không được hỗ trợ và đã bị xoá. Điều này không áp dụng cho workbox-webpack-plugin, vốn hỗ trợ mode trong trình bổ trợ InjectManifest.
Công cụ xây dựng yêu cầu Node.js phiên bản 10 trở lên
Các phiên bản Node.js trước phiên bản 10 không còn được hỗ trợ cho workbox-webpack-plugin, workbox-build hoặc workbox-cli. Nếu bạn đang chạy phiên bản Node.js cũ hơn phiên bản 8, hãy cập nhật môi trường thời gian chạy lên phiên bản được hỗ trợ.
Những điểm cải tiến mới
workbox-strategies
Workbox phiên bản 6 giới thiệu một cách mới để các nhà phát triển bên thứ ba xác định chiến lược Workbox của riêng họ. Điều này đảm bảo các nhà phát triển bên thứ ba có khả năng mở rộng Workbox theo cách đáp ứng đầy đủ nhu cầu của họ.
Lớp cơ sở Strategy mới
Trong phiên bản 6, tất cả các lớp chiến lược Workbox phải mở rộng lớp cơ sở Strategy mới. Tất cả chiến lược tích hợp sẵn đều được viết lại để hỗ trợ việc này.
Lớp cơ sở Strategy chịu trách nhiệm về hai việc chính:
- Gọi các phương thức gọi lại trong vòng đời của trình bổ trợ chung cho tất cả trình xử lý chiến lược (ví dụ: khi chúng bắt đầu, phản hồi và kết thúc).
- Tạo một thực thể "trình xử lý" có thể quản lý trạng thái cho từng yêu cầu riêng lẻ mà một chiến lược đang xử lý.
Lớp "trình xử lý" mới
Trước đây, chúng tôi có các mô-đun nội bộ gọi fetchWrapper và cacheWrapper, (như tên gọi của chúng) gói các API tìm nạp và lưu vào bộ nhớ đệm khác nhau bằng các hook vào vòng đời của chúng. Đây là cơ chế hiện cho phép các trình bổ trợ hoạt động, nhưng không được cung cấp cho nhà phát triển.
Lớp "trình xử lý" mới, StrategyHandler, sẽ hiển thị các phương thức này để các chiến lược tuỳ chỉnh có thể gọi fetch() hoặc cacheMatch() và tự động gọi mọi trình bổ trợ đã được thêm vào thực thể chiến lược.
Lớp này cũng giúp nhà phát triển có thể thêm các lệnh gọi lại tuỳ chỉnh, theo vòng đời của riêng họ, có thể dành riêng cho chiến lược của họ và chúng sẽ "hoạt động" với giao diện trình bổ trợ hiện có.
Trạng thái vòng đời mới của trình bổ trợ
Trong Workbox phiên bản 5, trình bổ trợ không có trạng thái. Điều đó có nghĩa là nếu một yêu cầu cho /index.html kích hoạt cả lệnh gọi lại requestWillFetch và cachedResponseWillBeUsed, thì hai lệnh gọi lại đó không có cách nào để giao tiếp với nhau hoặc thậm chí không biết rằng chúng được kích hoạt bởi cùng một yêu cầu.
Trong phiên bản 6, tất cả lệnh gọi lại của trình bổ trợ cũng sẽ được truyền một đối tượng state mới. Đối tượng trạng thái này sẽ là duy nhất cho đối tượng trình bổ trợ cụ thể này và lệnh gọi chiến lược cụ thể này (tức là lệnh gọi đến handle()). Điều này cho phép nhà phát triển viết trình bổ trợ, trong đó một lệnh gọi lại có thể thực hiện một việc nào đó dựa trên những gì một lệnh gọi lại khác trong cùng một trình bổ trợ đã thực hiện (ví dụ: tính toán chênh lệch thời gian giữa việc chạy requestWillFetch và fetchDidSucceed hoặc fetchDidFail).
Lệnh gọi lại mới trong vòng đời của trình bổ trợ
Các lệnh gọi lại mới trong vòng đời của trình bổ trợ đã được thêm vào để cho phép nhà phát triển tận dụng tối đa trạng thái vòng đời của trình bổ trợ:
handlerWillStart: được gọi trước khi bất kỳ logic trình xử lý nào bắt đầu chạy. Bạn có thể dùng lệnh gọi lại này để đặt trạng thái trình xử lý ban đầu (ví dụ: ghi lại thời gian bắt đầu).handlerWillRespond: được gọi trước khi phương thứchandle()của chiến lược trả về phản hồi. Bạn có thể dùng lệnh gọi lại này để sửa đổi phản hồi đó trước khi trả về phản hồi cho trình xử lý tuyến hoặc logic tuỳ chỉnh khác.handlerDidRespond: được gọi sau khi phương thứchandle()của chiến lược trả về một phản hồi. Bạn có thể dùng lệnh gọi lại này để 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 thay đổi.handlerDidComplete: được gọi sau khi tất cả lời hứa kéo dài thời gian hoạt động được thêm vào sự kiện từ lệnh gọi chiến lược này đã được giải quyết. Bạn có thể dùng lệnh gọi lại này để báo cáo về mọi dữ liệu cần đợi cho đến khi trình xử lý hoàn tất để tính toán (ví dụ: trạng thái kết quả tìm kiếm trong bộ nhớ cache, độ trễ của bộ nhớ đệm, độ trễ của mạng).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. Bạn có thể sử dụng lệnh gọi lại này để cung cấp nội dung "dự phòng" thay cho lỗi mạng.
Nhà phát triển triển khai chiến lược tuỳ chỉnh của riêng họ không phải lo lắng về việc tự gọi các lệnh gọi lại này; tất cả đều được xử lý bằng một lớp cơ sở Strategy mới.
Các loại TypeScript chính xác hơn cho trình xử lý
Đã chuẩn hoá các định nghĩa TypeScript cho nhiều phương thức gọi lại. Điều này sẽ mang lại trải nghiệm tốt hơn cho những nhà phát triển sử dụng TypeScript và tự viết mã để triển khai hoặc gọi trình xử lý.
workbox-window
Phương thức messageSkipWaiting() mới
Một phương thức mới, messageSkipWaiting(), đã được thêm vào mô-đun workbox-window để đơn giản hoá quy trình yêu cầu nhân viên dịch vụ "đang chờ" kích hoạt. Điều này mang lại một số điểm cải tiến:
- Hàm này gọi
postMessage()bằng nội dung thư chuẩn trên thực tế,{type: 'SKIP_WAITING'}, mà một trình chạy dịch vụ do Workbox tạo ra sẽ kiểm tra để kích hoạtskipWaiting(). - Nó chọn đúng trình chạy dịch vụ "đang chờ" để đăng thông báo này, ngay cả khi đó không phải là trình chạy dịch vụ mà
workbox-windowđã đăng ký.
Xoá các sự kiện "bên ngoài" để ưu tiên thuộc tính isExternal
Tất cả sự kiện "bên ngoài" trong workbox-window đã bị xoá và thay thế bằng các sự kiện "bình thường" có thuộc tính isExternal được đặt thành true. Điều này cho phép các nhà phát triển quan tâm đến sự khác biệt vẫn phát hiện được sự khác biệt đó, còn các nhà phát triển không cần biết có thể bỏ qua thuộc tính này.
Công thức "Cung cấp tính năng tải lại trang cho người dùng" gọn gàng hơn
Nhờ cả hai thay đổi nêu trên, công thức "Cung cấp tính năng tải lại trang cho người dùng" có thể được đơn giản hoá:
// v6:
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
const showSkipWaitingPrompt = () => {
// This assumes a hypothetical createUIPrompt() method with
// onAccept and onReject callbacks:
const prompt = createUIPrompt({
onAccept: () => {
wb.addEventListener('controlling', () => {
window.location.reload();
});
// This will postMessage() to the waiting service worker.
wb.messageSkipWaiting();
},
onReject: () => {
prompt.dismiss();
},
});
};
// Listening for externalwaiting is no longer needed.
wb.addEventListener('waiting', showSkipWaitingPrompt);
wb.register();
}
</script>
workbox-routing
Một tham số boolean mới, sameOrigin, được truyền đến hàm matchCallback dùng trong workbox-routing. Giá trị này được đặt thành true nếu yêu cầu là dành cho một URL cùng nguồn gốc và false nếu không phải.
Điều này giúp đơn giản hoá một số mã nguyên mẫu phổ biến:
// In v5:
registerRoute(
({url}) =>
url.origin === self.location.origin && url.pathname.endsWith('.png'),
new StaleWhileRevalidate({cacheName: 'local-png'})
);
// In v6:
registerRoute(
({sameOrigin, url}) => sameOrigin && url.pathname.endsWith('.png'),
new StaleWhileRevalidate({cacheName: 'local-png'})
);
matchOptions trong workbox-expiration
Giờ đây, bạn có thể đặt matchOptions trong workbox-expiration. Sau đó, giá trị này sẽ được truyền dưới dạng CacheQueryOptions đến lệnh gọi cache.delete() cơ bản. (Hầu hết các nhà phát triển sẽ không cần làm việc này.)
workbox-precaching
Sử dụng workbox-strategies
workbox-precaching đã được viết lại để sử dụng workbox-strategies làm cơ sở. Việc này sẽ không gây ra bất kỳ thay đổi có thể gây lỗi nào và sẽ giúp cải thiện tính nhất quán lâu dài trong cách hai mô-đun truy cập vào mạng và bộ nhớ đệm.
Tính năng lưu trước vào bộ nhớ đệm hiện xử lý từng mục một, không xử lý hàng loạt
workbox-precaching đã được cập nhật để mỗi lần chỉ yêu cầu và lưu một mục trong tệp kê khai lưu trước vào bộ nhớ đệm, thay vì cố gắng yêu cầu và lưu tất cả các mục cùng một lúc (để trình duyệt tự tìm cách điều tiết).
Điều này sẽ làm giảm khả năng xảy ra lỗi net::ERR_INSUFFICIENT_RESOURCES trong khi lưu trước vào bộ nhớ đệm, đồng thời cũng giảm tranh chấp băng thông giữa việc lưu trước vào bộ nhớ đệm và các yêu cầu đồng thời do ứng dụng web đưa ra.
PrecacheFallbackPlugin giúp dễ dàng dự phòng khi không có mạng
workbox-precaching hiện bao gồm PrecacheFallbackPlugin, triển khai phương thức vòng đời handlerDidError mới được thêm vào phiên bản 6.
Điều này giúp bạn dễ dàng chỉ định một URL được lưu trước vào bộ nhớ đệm làm "dự phòng" cho một chiến lược nhất định khi không có phản hồi. Trình bổ trợ sẽ đảm nhận việc tạo đúng khoá bộ nhớ đệm cho URL được lưu trước vào bộ nhớ đệm, bao gồm cả mọi tham số sửa đổi cần thiết.
Dưới đây là ví dụ về cách sử dụng trình xử lý này để phản hồi bằng /offline.html được lưu trước vào bộ nhớ đệm khi chiến lược NetworkOnly không thể tạo phản hồi cho yêu cầu điều hướng (nói cách khác là hiển thị trang HTML ngoại tuyến tuỳ chỉnh):
import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
({request}) => request.mode === 'navigate',
new NetworkOnly({
plugins: [
new PrecacheFallbackPlugin({
fallbackURL: '/offline.html',
}),
],
})
);
precacheFallback trong bộ nhớ đệm thời gian chạy
Nếu đang sử dụng generateSW để tạo trình chạy dịch vụ thay vì viết trình chạy dịch vụ theo cách thủ công, bạn có thể sử dụng tuỳ chọn cấu hình precacheFallback mới trong runtimeCaching để thực hiện việc tương tự:
{
// ... other generateSW config options...
runtimeCaching: [{
urlPattern: ({request}) => request.mode === 'navigate',
handler: 'NetworkOnly',
options: {
precacheFallback: {
// This URL needs to be included in your precache manifest.
fallbackURL: '/offline.html',
},
},
}],
}
Nhận Trợ giúp
Chúng tôi dự kiến hầu hết các quá trình di chuyển sẽ diễn ra suôn sẻ. Nếu bạn gặp phải vấn đề không được đề cập trong hướng dẫn này, vui lòng cho chúng tôi biết bằng cách mở một vấn đề trên GitHub.