如何使用Service Workers预缓存名称在每次部署时都会更改的资产?

3
我们正在使用Workbox来预缓存“下一个”页面的一些资源,但我们的资源URL包含部署日期和哈希值,例如“/css/2019-05-15/f00ba5/home.css”。
我们面临的问题是如何将URL的变化部分(“2019-05-15/f00ba5”)传递给service worker,并使Workbox预缓存资产列表。
我们正在使用Workbox,我们尝试使用workbox-window从网页向SW发送消息,直到这里......它工作了!
但现在,由于SW知道哈希值,我们不知道如何利用它,因为如果我们从事件监听器中调用workbox.precaching.precacheAndRoute()方法,导入workbox.precaching模块会以某种方式失败。
在page.html中。
<script type="module">
    import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/4.0.0/workbox-window.prod.mjs';

    if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
        const wb = new Workbox('/service-worker.js');
        wb.messageSW({type: 'hash', payload: "12345"});
        wb.register();
    })
}
</script>

在 service-worker.js 中

const file1 = "/css/{hash}/home.css";
const file2 = "/js/{hash}/home.js";
const file3 = "/img/{hash}/hero.jpg";

addEventListener('message', (event) => {
    if (event.data.type === 'hash') {
        // TODO: replace {hash} with event.data.payload in file1, 2, 3
        const precacheManifest = [ file1, file2, file3 ];
        workbox.precaching.precacheAndRoute(precacheManifest);
    }
});

我遇到了错误

workbox-sw.js:1 Unable to import module 'workbox-precaching' from 'https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js'.
loadModule @ workbox-sw.js:1
get @ workbox-sw.js:1
(anonymous) @ service-worker.js:39
workbox-sw.js:1 Uncaught DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js' failed to load.
at Object.loadModule (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js:1:954)
at Object.get (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js:1:727)
at https://brioni.f31.lcl/service-worker.js:39:13
loadModule @ workbox-sw.js:1
get @ workbox-sw.js:1
(anonymous) @ service-worker.js:39
framework.js:1441 STORE::LazyLoad.Init

我预计这会起作用,并且会预先缓存 precacheManifest 数组中的文件。
1个回答

1
您遇到的特定错误是由于在服务工作者安装完成后调用importScripts()的限制引起的,这是通过workbox-sw库在后台发生的。在Workbox documentation中更详细地描述了这一点,以及实现相同效果的替代方法。
话虽如此,使用workbox-precaching“动态”不是一个很好的选择。正如workbox-precaching documentation中所述,您应该使用构建工具(如workbox-cliworkbox-webpack-plugin)生成此列表,并自动将预缓存清单插入服务工作者文件中。由于更新的预缓存清单而导致的服务工作者文件的更改将触发服务工作者更新生命周期事件,从而确保您的预缓存资产始终保持最新状态。
如果您不想使用构建工具并提前生成预缓存清单,那么设置路由规则并使用运行时缓存策略比预缓存更合适。您可以使用workbox-window传入您希望在运行时缓存的URL列表

谢谢Jeff的解释,比起仅有的文档,现在我更加清楚了一些。不幸的是,生成哈希的构建过程超出了我们的控制范围,我担心在那个阶段它无法产生新的文件以部署。我们可能会使用服务器端语言来生成service-worker.js文件,因为服务器知道要放在URL中的部署哈希。 - verlok
个人而言,我的软件会调用一个名为 version.json 的文件,其中包含要获取的文件以及哈希值以确定是否有差异。与其每次部署时杀死和安装/激活新软件,我更喜欢这种方法。 - ekans

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接