เอกสารประกอบนี้เน้นที่การแคชล่วงหน้าเป็นหลัก โดยมักจะกล่าวถึงเครื่องมือสร้าง generateSW
และ injectManifest
แม้ว่าจะมีเหตุผลที่ดีมากมายในการรวมตรรกะการแคชล่วงหน้าไว้ใน Service Worker แต่คุณไม่จำเป็นต้องใช้การแคชล่วงหน้าเพื่อใช้ Workbox
บางทีโปรเจ็กต์ของคุณอาจต้องการแคชรันไทม์เท่านั้น หรือบางทีคุณอาจต้องการวิธีผสานรวม Service Worker API ที่เรียบร้อยกว่า เช่น Web Push กรณีต่อไปนี้คือกรณีที่คุณไม่ต้องการให้ใช้เครื่องมือสร้างของ Workbox ซึ่งเราได้อธิบายไว้ในบทความนี้
เมื่อใช้เครื่องมือรวม
เครื่องมือจัดกลุ่มมีบทบาทสำคัญในแวดวงการพัฒนาเว็บ และโปรเจ็กต์ของคุณก็อาจใช้เครื่องมือนี้อยู่ ในกรณีนี้ โปรดทราบว่าคุณไม่จำเป็นต้องใช้ปลั๊กอินเครื่องมือจัดกลุ่ม (เช่น workbox-webpack-plugin
) หากไม่ได้แคชล่วงหน้า คุณจะถือว่า Service Worker เป็นจุดแรกเข้าแยกต่างหากในแอปพลิเคชัน
คุณจะต้องสร้าง Service Worker และใช้โมดูล Workbox ตามที่แอปพลิเคชันต้องการในรูทของไดเรกทอรีซอร์สของโปรเจ็กต์ ต่อไปนี้คือตัวอย่างที่ไม่มีการคุกเก็บข้อมูลล่วงหน้า ซึ่งตั้งค่ากลยุทธ์การแคชสำหรับคำขอการนำทางและชิ้นงานรูปภาพในอินสแตนซ์ Cache
แยกต่างหากแทน
// 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);
จากตรงนี้ คุณต้องระบุ Service Worker นี้เป็นจุดแรกเข้าในเครื่องมือรวมที่คุณเลือก ด้านล่างนี้คือตัวอย่างวิธีดำเนินการในเครื่องมือจัดกลุ่มยอดนิยม 2-3 รายการ
webpack
webpack ยอมรับจุดแรกเข้าในการกำหนดค่า entry
สิ่งที่ควรทราบเมื่อใช้แนวทางนี้
- คุณต้องแสดงผล Service Worker ไปยังรูทของไดเรกทอรีเอาต์พุตเพื่อให้ Service Worker มีขอบเขตที่กว้างที่สุด
- คุณไม่ต้องการให้ Service Worker มีเวอร์ชัน เนื่องจากอัปเดต Service Worker จะสร้างแฮชใหม่ซึ่งอาจส่งผลให้มีการติดตั้งใช้งาน Service Worker หลายรายการในเว็บไซต์
เพื่อให้เป็นไปตามเงื่อนไขข้างต้น ระบบจะส่งฟังก์ชันไปยัง output.filename
ซึ่งจะตรวจสอบว่าจุดแรกเข้าที่ประมวลผลอยู่นี้เป็นจุดแรกเข้าของ Service Worker หรือไม่ ไม่เช่นนั้นระบบจะเขียนไฟล์ที่มีเวอร์ชันไปยังปลายทางปกติ
// 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
}
};
รายงาน
Rollup มีลักษณะคล้ายกับ webpack ยกเว้นจะมีการระบุจุดแรกเข้าหลายจุดเป็นออบเจ็กต์การกําหนดค่าแยกต่างหากที่ส่งออกในอาร์เรย์
// 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 มีอินเทอร์เฟซบรรทัดคำสั่งที่ไม่ซับซ้อน:
npx esbuild ./src/sw.js --bundle --minify --outfile=./dist/sw.js
esbuild จะแทนที่ process.env.NODE_ENV ด้วย "development" โดยค่าเริ่มต้น หรือ "production" หากเปิดใช้การทำให้ไฟล์เล็กลง
ไม่ใช้ Bundler ที่ใช้ workbox-sw
โปรเจ็กต์อาจไม่ได้ใช้เครื่องมือจัดกลุ่มเลย workbox-sw
โหลดรันไทม์ของ Workbox ให้คุณได้จาก CDN ภายใน Service Worker ของคุณ และไม่มีขั้นตอนการสร้างบิลด์หากคุณนำเข้าด้วย 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);
หากการโหลดรันไทม์ Workbox จาก CDN ดูเหมือนจะไม่ค่อยดีนัก คุณก็ใช้ workbox-sw
กับ URL ในเครื่องได้
บทสรุป
เมื่อทราบวิธีใช้ Workbox โดยไม่ต้องแคชล่วงหน้าแล้ว คุณก็ไม่ต้องผูกมัดกับ Bundler หรือเครื่องมือสร้างใดๆ อีกต่อไป ซึ่งช่วยให้คุณมีความยืดหยุ่นในการสร้าง Service Worker ด้วยตนเองโดยใช้เพียงโค้ดแคชรันไทม์ของ Workbox ที่คุณสนใจ