Cho đến nay, tài liệu này đã đề cập rất nhiều đến việc lưu vào bộ nhớ đệm và thường nói đến các công cụ xây dựng generateSW
và injectManifest
. Mặc dù có nhiều lý do chính đáng để đưa logic vào bộ nhớ đệm trong trình chạy dịch vụ, nhưng bạn không cần phải sử dụng tính năng lưu vào bộ nhớ đệm để sử dụng Hộp làm việc.
Có thể dự án của bạn chỉ cần lưu vào bộ nhớ đệm trong thời gian chạy hoặc có thể bạn muốn tích hợp các API trình chạy dịch vụ theo cách gọn gàng hơn, chẳng hạn như công cụ đẩy web. Đây là những trường hợp bạn không muốn sử dụng các công cụ xây dựng của Workbox. Đó cũng là nội dung được đề cập trong bài viết này.
Khi sử dụng trình tạo gói
Trình cung cấp thông tin rất nổi bật trong bối cảnh phát triển web và rất có khả năng dự án của bạn đang sử dụng bộ công cụ này. Trong trường hợp này, bạn cần biết rằng không cần sử dụng trình bổ trợ gói (như workbox-webpack-plugin
) nếu không lưu bất cứ thứ gì vào bộ nhớ đệm. Bạn sẽ coi worker dịch vụ là một điểm truy cập riêng biệt trong ứng dụng.
Trong thư mục gốc của thư mục nguồn dự án, bạn sẽ tạo một worker dịch vụ và sử dụng mọi mô-đun Workbox mà ứng dụng của bạn yêu cầu. Dưới đây là một ví dụ không cần lưu vào bộ nhớ đệm về cách thiết lập chiến lược lưu vào bộ nhớ đệm cho các yêu cầu điều hướng và yêu cầu thành phần hình ảnh trong các thực thể Cache
riêng biệt:
// sw.js
import {NetworkFirst, CacheFirst} from 'workbox-strategies';
import {registerRoute, NavigationRoute, Route} from 'workbox-routing';
const navigationRoute = new NavigationRoute(new NetworkFirst({
cacheName: 'navigations'
}));
const imageAssetRoute = new Route(({request}) => {
return request.destination === 'image';
}, new CacheFirst({
cacheName: 'image-assets'
}));
registerRoute(navigationRoute);
registerRoute(imageAssetRoute);
Từ đây, bạn cần chỉ định trình chạy dịch vụ này làm điểm truy cập trong bộ gói mà bạn chọn. Dưới đây là một số ví dụ về cách thực hiện việc đó trong một số trình tạo gói phổ biến.
gói web
webpack chấp nhận các điểm truy cập trong cấu hình entry
. Có một số điều cần lưu ý khi sử dụng phương pháp này:
- Để đảm bảo worker dịch vụ có phạm vi rộng nhất có thể, bạn nên xuất worker dịch vụ đó đến thư mục gốc của thư mục đầu ra.
- Bạn không nên tạo phiên bản cho worker dịch vụ vì các bản cập nhật cho worker dịch vụ sẽ tạo ra các hàm băm mới có thể dẫn đến việc nhiều worker dịch vụ được triển khai trên trang web của bạn.
Để đáp ứng các điều kiện trên, bạn có thể truyền một hàm đến output.filename
để kiểm tra xem điểm truy cập hiện tại đang được xử lý có phải là điểm truy cập của trình chạy dịch vụ hay không. Nếu không, các tệp có phiên bản sẽ được ghi vào đích đến thông thường.
// webpack.config.js
import process from 'process';
const isProd = process.env.NODE_ENV === 'production';
export default {
mode: isProd ? 'production' : 'development',
context: process.cwd(),
entry: {
// Service worker entry point:
sw: './src/sw.js',
// Application entry point:
app: './src/index.js'
},
output: {
filename: ({runtime}) => {
// Check if the current filename is for the service worker:
if (runtime === 'sw') {
// Output a service worker in the root of the dist directory
// Also, ensure the output file name doesn't have a hash in it
return '[name].js';
}
// Otherwise, output files as normal
return 'js/[name].[contenthash:8].js';
},
path: './dist',
publicPath: '/',
clean: true
}
};
tổng hợp
Rollup cũng tương tự như webpack, ngoại trừ việc nhiều điểm truy cập được chỉ định dưới dạng các đối tượng cấu hình riêng biệt được xuất trong một mảng:
// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
// Plugins common to both entry points
const plugins = [
nodeResolve(),
];
export default [
// Application entry point
{
input: './src/index.js',
output: {
dir: './dist/js',
format: 'esm'
},
plugins
},
// Service worker entry point
{
input: './src/sw.js',
output: {
file: './dist/sw.js',
format: 'iife'
},
plugins: [
...plugins,
// This @rollup/plugin-replace instance replaces process.env.NODE_ENV
// statements in the Workbox libraries to match your current environment.
// This changes whether logging is enabled ('development') or disabled ('production').
replace({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
})
]
}
];
esbuild
esbuild cung cấp một giao diện dòng lệnh đơn giản:
npx esbuild ./src/sw.js --bundle --minify --outfile=./dist/sw.js
Theo mặc định, esbuild sẽ thay thế process.env.NODE_ENV bằng "development" hoặc "production" nếu bạn bật tính năng rút gọn.
Không có trình gói dịch vụ bằng cách sử dụng workbox-sw
Dự án của bạn thậm chí có thể không sử dụng trình tạo gói. workbox-sw
có thể tải môi trường thời gian chạy Workbox cho bạn từ CDN trong trình chạy dịch vụ của bạn và không cần bước tạo bản dựng nếu bạn nhập bằng importScripts
:
// sw.js
// Imports Workbox from the CDN. Note that "6.2.0" of the URL
// is the version of the Workbox runtime.
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-sw.js');
const navigationRoute = new workbox.routing.NavigationRoute(new workbox.strategies.NetworkFirst({
cacheName: 'navigations'
}));
const imageAssetRoute = new workbox.routing.Route(({request}) => {
return request.destination === 'image';
}, new workbox.strategies.CacheFirst({
cacheName: 'image-assets'
}));
workbox.routing.registerRoute(navigationRoute);
workbox.routing.registerRoute(staticAssetRoute);
Nếu không có nhiều triển vọng về việc tải thời gian chạy Workbox từ CDN, bạn có thể sử dụng workbox-sw
với URL cục bộ.
Kết luận
Giờ đây, bạn đã biết cách sử dụng Workbox mà không cần lưu trước vào bộ nhớ đệm, bạn không còn bị ràng buộc với một trình đóng gói hoặc công cụ bản dựng cụ thể nữa. Điều này mang lại cho bạn sự linh hoạt để tạo một trình chạy dịch vụ chỉ bằng một phần nhỏ mã lưu vào bộ nhớ đệm trong thời gian chạy của Workbox mà bạn quan tâm.