==============================================================
记录把 service worker 切æ¢åˆ°ç”± Workbox 生æˆçš„过程 ã€æµæ°´å¸ã€‘
==============================================================
:slug: switch-to-workbox
:date: 2021-10-24 17:39
:lang: zh_hans
:color: #E8710A
:tags: frontend, service-worker, workbox, javascript
:mykeywords: frontend,å‰ç«¯,service-worker,workbox,sw-precache
:description: 记录把 service worker 切æ¢åˆ° Workbox
:noindent: true
:summary:
.. contents::
我把网站的 service worker 从 sw-precache è¿ç§»åˆ°äº† Workbox ,记录一下过程。
sw-precache 是 Google 的一个实验性项目,也是 Workbox çš„å‰èº«ä¹‹ä¸€ï¼Œä¹‹å‰ä¸€ç›´ç”¨çš„它æ¥ç”Ÿæˆç½‘站的 service worker 文件,å¯å³ä½¿å¯¹äºŽæˆ‘这个挺简å•çš„站点,用它现在也有点ä¸å¤Ÿç”¨ï¼Œæ¯”如之å‰æˆ‘是缓å˜æˆ‘的所有指定页é¢ï¼Œä»¥å¤‡ç¦»çº¿ä½¿ç”¨ï¼Œä½†æ˜¯æˆ‘现在我觉得ä¸å¦¥ï¼Œåªç¼“å˜è®¿é—®é¡µæ›´å¥½ï¼›å†æ¯”如以å‰æ¯æ¬¡è®¿é—®çš„时候都是先获å–的离线内容,å†å°è¯•æ›´æ–°åœ¨çº¿å†…容,我现在也觉得ä¸å¥½ï¼Œåº”è¯¥æ ¹æ®å†…容的ä¸åŒæ¥åˆ¤å®šå…ˆè®¿é—®å“ªé‡Œçš„内容,而达æˆè¿™äº›éœ€è¦åšå¾ˆå¤šçš„工作æ‰èƒ½æ»¡è¶³ï¼Œå°±ç›´æŽ¥æ¢äº†ã€‚
下é¢è¯´è¯´è¿‡ç¨‹..
.. PELICAN_END_SUMMARY
对于未系统化了解过 JS 项目管ç†å·¥å…·çš„我æ¥è¯´ï¼Œçœ‹ Workbox 的简介我是懵的,什么支æŒé€šè¿‡ Javascript 模å—æ¥ä½¿ç”¨ï¼Œä½†æ˜¯ service worker ä¸æ”¯æŒæ¨¡å—,所以需è¦ä½¿ç”¨ bunlder 工具æ¥ç»Ÿåˆæˆä¸€ä¸ªæ–‡ä»¶.. 在一开始,就被这个 bunlder 工具的选择和使用难到了。
介ç»é‡Œåˆ—出了三ç§å·¥å…· webpack , Rollup ä»¥åŠ Parcel 。我先è€ç€æ€§å基本æµè§ˆäº†ä¸€é Workbox 的介ç»ï¼Œå…¨æ–‡æ²¡è¯´æŽ¨èçš„å·¥å…·ã€‚ã€‚äºŽæ˜¯æˆ‘æ ¹æ® tooling.report 上的通过率选择了 Parcel ,跟ç€å…¶æ–‡æ¡£æ“作了一éåŽå‘现。。 没把模å—都整åˆè¿›åŽ»å•Šï¼Œè¿˜æ˜¯ä¼šéœ€è¦å¯¼å…¥å¤–部的 js 文件,这就对 service worker ä¸é€‚用了。åŽæ¥åˆè¯•äº†ä¸€ä¸‹ Github 星多的 webpack .. 很满æ„,一下å就生æˆäº†æˆ‘需è¦çš„文件。
在这个过程ä¸ï¼Œè¿˜äº†è§£åˆ°äº† node.js 的项目管ç†æ–‡ä»¶ :file:`package.json` 里的一点基本内容,比如 :code:`devDependencies` 是用æ¥æ”¾å¼€å‘用工具的, :code:`dependencies` 则是用æ¥æ”¾å®žé™…的项目ä¾èµ–的,它好åƒä¼šæ ¹æ® Git 项目的环境æ¥æŸ¥æ‰¾å½“å‰çš„é¡¹ç›®æ ¹ç›®å½•ï¼Œè‡ªæ¤ï¼Œæˆ‘å°±å¯ä»¥æŠŠè¿™ä¸ªé¡¹ç›®çŽ¯å¢ƒå½“作一个独立的系统环境æ¥å¯¹å¾…了,然åŽå°±å¯¹å…¶å·¥å…·å’Œä¾èµ–有了一个比较清晰的认知。
接下æ¥å°±æ˜¯ä¸€ä¸ªæ¯”较é‡å¤´çš„如何编写原始的 service worker 文件,我å°è¯•å¤åˆ¶äº†å…¶ **Routing and Caching Strategies** 的示例直接使用,å‘现基本上满足了我的需求,这时候自己还需è¦é¢å¤–æ·»åŠ çš„å†…å®¹æ˜¯ç¦»çº¿è®¿é—®æœªç¼“å˜é¡µé¢æ—¶çš„ fallback é¡µï¼Œä¹Ÿæ ¹æ®ç¤ºä¾‹ç›´æŽ¥æ·»åŠ 了预缓å˜çš„并在缓å˜æœªèŽ·å–æ—¶ fallback 到指定页的代ç ,也直接æˆåŠŸäº†ã€‚这时候我感å¹ï¼Œå®žåœ¨å¤ªæ–¹ä¾¿äº†.. 我的è¦æ±‚好åƒå…¨éƒ¨è¾¾åˆ°äº†ã€‚
åŽæ¥ç®€å•æµ‹è¯•äº†ä¸€ä¸‹åŽå‘çŽ°ï¼Œå°±è¿™æ ·çš„ä»£ç 是ä¸ä¼šè‡ªåŠ¨è·³è¿‡æ–°çš„ service worker çš„ waiting 阶段的,虽然对于一些å¤åˆ¶çš„ web 应用æ¥è¯´ï¼Œå®ƒçš„ waiting 阶段是应该需è¦ç”¨æˆ·æ¥é€‰æ‹©æ˜¯å¦è·³è¿‡çš„,但对于我这个个人åšå®¢è€Œè¨€ï¼Œä¸å˜åœ¨åœ¨è®¿é—®æ—¶éœ€è¦ä¿ç•™çš„内容,所以应设定为自动跳过。
å‚考自己以å‰å†™çš„ service worker 文件,把 :code:`self.skipWaiting()` æ·»åŠ åˆ° server worker çš„ install 事件下åŽå¯ç”¨ã€‚考虑到需è¦åˆ 除之å‰ç¼“å˜çš„本地数æ®åº“,åŒæ ·æŠŠåˆ 除数æ®åº“çš„ä»»åŠ¡æ·»åŠ åˆ°äº†è¿™ä¸ªäº‹ä»¶ä¸‹ã€‚
这时候我在想,当阅读离线页é¢çš„时候,如果有一个简å•çš„æ示信æ¯å°±æ›´å¥½äº†ã€‚å› ä¸º service worker æ˜¯æ— æ³•èŽ·å– DOM 的,åªèƒ½é 消æ¯ä¸Žå…¶å®¢æˆ·ç«¯ï¼ˆé¡µé¢ï¼‰è¿›è¡Œé€šè®¯ï¼ŒäºŽæ˜¯æˆ‘开始去找 Workbox 有没有æ供类似的在抓缓å˜æ—¶ç”¨æ¥å’Œå®¢æˆ·ç«¯é€šè®¯çš„功能。一开始没找到,åŽæ¥å‘现了它å¯ä»¥è‡ªå®šä¹‰æ’件,而自定义æ’件的里é¢æ供了一个 :code:`handlerDidComplete` 方法,介ç»è¯´å®ƒå¯ä»¥èŽ·å–到缓å˜å‘½ä¸çš„状æ€ï¼Œæˆ‘ç»è¿‡å®žéªŒåŽå‘现,给出的å˜é‡éƒ½æŠ“ä¸åˆ°è¿”回的 Response 是从缓å˜æ‹¿åˆ°çš„还是网络拿到的(也å¯èƒ½æ˜¯æˆ‘没找到,ä¸ç®¡ï¼‰.. åŽæ¥æˆ‘å°±åˆç”¨äº†å®ƒå¦ä¸€ä¸ªæ–¹æ³• :code:`fetchDidFail` (顾åæ€ä¹‰å°±æ˜¯ä»Žç½‘络获å–失败了åŽä¼šè§¦å‘的),两个一结åˆï¼Œå‰è€…用于æä¾› Resonse 的状æ€ç (比如 200),åŽè€…用于告知客户端从网络获å–å¤±è´¥äº†ï¼Œè¿™æ ·ä¸€ç»„åˆå®¢æˆ·ç«¯å°±å¯ä»¥çŸ¥é“是ä¸æ˜¯ä»Žç¼“å˜èŽ·å–的内容了。
但是在这个过程ä¸ï¼Œæˆ‘åˆå‘现了一个问题。我的åšå®¢æ˜¯é™æ€çš„,ä¸é€šè¿‡æŽ¥æ”¶å‚æ•°æ¥èŽ·å–到ä¸åŒå†…容的,所以之å‰è®¾å®šäº†èŽ·å–缓å˜æ—¶ä¼šå¿½ç•¥æŽ‰ä»»ä½•å‚数,但 Workbox ä¼šæ ¹æ®è®¿é—®çš„完整 URL æ¥ä¿å˜ç¼“å˜ï¼Œè¿™æ ·å°±å¯¼è‡´äº†èŽ·å–缓å˜å¯èƒ½èŽ·å–到更旧的缓å˜ï¼Œæ‰€ä»¥æˆ‘得想办法在æ¯æ¬¡ç¼“å˜ä¿å˜å®Œä¹‹åŽï¼Œåˆ 除我认为相åŒçš„更旧的缓å˜ã€‚这里就åˆæœ‰ä¸€ä¸ªæ–¹æ³•å¯ä»¥ä½¿ç”¨äº†ï¼Œ :code:`cacheDidUpdate` åŒæ ·æ˜¯åœ¨è‡ªå®šä¹‰çš„æ’件里é¢ï¼Œä¼šåœ¨æ¯æ¬¡ç¼“å˜è¢«ä¿å˜æ—¶è§¦å‘,我在里é¢é€šè¿‡ Request 抓å–了所有缓å˜ï¼Œç„¶åŽèŽ·å–缓å˜å¤´çš„ :file:`date` 消æ¯æ¥åˆ¤æ–å¹¶åˆ é™¤æ›´æ—§çš„ç¼“å˜ã€‚
自æ¤ï¼Œåˆ‡æ¢ service worker 到 Workbox 实现完æˆã€‚
*åŽæ¥å‘现一个问题, Chrome 下测试没问题的离线页é¢ä¿¡æ¯æ示在 Firefox ä¸‹æ— æ•ˆ.. æš‚æ—¶ä¸ç®¡äº†..*