如何在workbox-build generateSW模式下配置带离线回退的默认处理器?
当Service Worker由Workbox驱动时,workbox-routing中的setDefaultHandler()易用且高度可自定义,但使用generateSW作为构建工具时除外。由于无法通过registerRoute或如下的urlPattern缓存HTML页面,默认处理器会采用NetworkFirst策略处理页面缓存:
({ request }) => request.mode === 'navigate',
我已为第三方资源注册了采用NetworkOnly策略的路由,运行正常;网站静态资源也已单独缓存。但小型静态HTML页面构建Service Worker时存在难点:/、/page1/、/page2/这类路径无法按预期缓存(注:/对应index.html,/page1/对应/page1/index.htm,/page2/对应/page2/index.htm)。
由于未为HTML页面注册其他路由,它们由默认处理器管理。以下是手动编写Service Worker文件时自定义的setDefaultHandler:
setDefaultHandler( new NetworkFirst({ networkTimeoutSeconds: 3, cacheName: 'runtime', plugins: [ new CacheableResponsePlugin({ statuses: [0, 200], }), new ExpirationPlugin({ maxEntries: 12, maxAgeSeconds: 60 * 60 * 24 * 15, // 15天 matchOptions: { ignoreVary: true }, }), ], }), );
基于Node的构建流程无法直接使用/自定义setDefaultHandler,默认值似乎是NetworkOnly且无法修改。参考相关方案后,我在build.js中加入如下代码片段,通过路由匹配的缓存策略实现HTML页面缓存:
const {generateSW} = require('workbox-build'); // 注意离线回退的无限循环问题! // 桌面端运行正常,但移动端不稳定 // precacheFallback在我的网站中导致异常行为 function matchFunction({ url }) { const pages = ['/', '/page1/', '/page2/', '/.../']; return pages.includes(url.pathname); } generateSW({ // ... 其他generateSW配置选项... runtimeCaching: [ { urlPattern: matchFunction, handler: 'NetworkFirst', options: { networkTimeoutSeconds: 3, cacheName: 'runtime', cacheableResponse: { statuses: [0, 200] }, expiration: { maxEntries: 12, maxAgeSeconds: 60 * 60 * 24 * 15, // 15天 matchOptions: { ignoreVary: true }, }, precacheFallback: { fallbackURL: 'offline.html', }, }, }, // ... 其他runtimeCaching选项... ], });
根据Workbox核心团队成员的说明,自定义处理器是在build.js中为运行时缓存设置默认处理器的一种方法,但我不确定如何硬编码实现。
3月20日补充说明
我更倾向于在运行时缓存中使用正则表达式而非matchFunction。该正则路由仅匹配HTML文档:
const {generateSW} = require('workbox-build'); generateSW({ // ... 其他generateSW配置选项... runtimeCaching: [ { urlPattern: RegExp('^[^.]+$'), // 其他选项无变化 }, // ... 其他runtimeCaching选项... ], });
我修改了问题并添加了离线回退选项。结合正则与带离线回退的自定义处理器将是完美解决方案,希望precacheFallback并非workbox-build generateSW模式下的唯一选择。
是否可以结合workbox-recipes中的offlineFallback()与自定义处理器?我尝试了如下方案,但不确定是否可行:
const {generateSW} = require('workbox-build'); const pageFallback = '/offline.html'; // 我需要弄清楚如何在workbox-build generateSW模式下将offline.html添加到默认缓存名称 // (workbox-offline-fallbacks) // 自定义处理器应基于'workbox-offline-fallbacks' const customHandler = async offline => { const destination = offline.request.destination; const cache = await self.caches.open('workbox-offline-fallbacks'); if (destination === 'document') { return (await cache.match(pageFallback)) || Response.error(); } return Response.error(); }; generateSW({ // ... 其他generateSW配置选项... runtimeCaching: [ { urlPattern: (customHandler, RegExp('^[^.]+$')), // 不使用precacheFallback }, // ... 其他runtimeCaching选项... ], });
自定义处理器可确保运行时缓存流畅,但该方案缺少离线回退功能。现寻求在generateSW模式下配置带离线回退的默认处理器的可行方案。
内容的提问来源于stack exchange,提问作者druzsik

