如何使用服务工作者预缓存名称在每次部署时都会更改的资产?

How to precache assets with names that change at every deploy using service workers?

我们正在使用 Workbox 预缓存 "next" 页面的一些资产,但我们的资产 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>

服务中-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 数组中。

您 运行 遇到的特定错误是由于安装服务工作者后调用 importScripts() 的限制,这是通过 workbox-sw 在幕后发生的图书馆。它在 Workbox documentation 中有更详细的描述,以及完成相同事情的替代方法。

也就是说,使用 workbox-precaching "dynamically" 并不是一个好的选择。如 workbox-precaching documentation 中所述,您应该使用 workbox-cliworkbox-webpack-plugin 等构建工具来生成此列表并自动将预缓存清单插入到您的服务工作者文件中。由于更新的预缓存清单而对服务工作者文件进行的更改将触发服务工作者更新生命周期事件,这反过来又会确保您的预缓存资产保持最新。

如果您不想使用构建工具并提前生成预缓存清单,则设置要在运行时缓存的routing rules and using a runtime caching strategy is more appropriate than precaching. You can use workbox-window to pass in a list of URLs