React 应用程序与 Service Worker - 在新版本上强制更新浏览器缓存
React application with Service Worker - Force update of browser cache on new version
我的应用程序是用 Reac / Redux 编写的,并使用 Workbox 生成我的服务工作者。
这有效 - 我可以确认在 运行 "workbox inject:manifest".
时生成的服务工作者中的修订已更新
但是,我注意到客户端在新版本发布后不会更新缓存,新代码只会在多次刷新后加载。对于每个版本,我都确认修订已更新。
到目前为止,我尝试强制浏览器在新版本发布后清除缓存的方法是:
- 在我的 ServiceWorker 中实现了 skipWaiting() - 正确显示更新警报
- 添加了缓存 headers 以禁用 serviceWorker.js 和 css 文件的缓存(见下文)
- 将 [contenthash] 添加到我在 Webpack 中的所有捆绑文件,并为每个版本相应地更新 index.html
缓存headers
<IfModule mod_headers.c>
Header unset ETag
<IfModule mod_alias.c>
# disable browser cache for serviceWorker.js file
<FilesMatch "^(serviceWorker.js)$">
Header unset Expires
Header set Cache-Control "max-age=0"
</FilesMatch>
<FilesMatch "\.(js|css)$">
# cache for 24 hours = 86400 seconds
Header set Cache-Control "max-age=86400, public, no-transform, must-revalidate"
</FilesMatch>
</IfModule>
</IfModule>
index.html
...
<body style="overflow: hidden">
<div id="app"></div>
<script src="/dist/main.bundle.aae6d2bb162cbee13899.js"></script>
<script src="/dist/0.bundle.aaa837f16bb646266d99.js"></script>
<script src="/dist/1.bundle.aa653fe9abbe232be599.js"></script>
<script src="/dist/2.bundle.aa3096daabb2d428a899.js"></script>
<script src="/dist/3.bundle.aa1650fc5bb4e1f1ea99.js"></script>
<script src="/dist/4.bundle.aae80e50cbb06d5e5599.js"></script>
<script src="/dist/5.bundle.aa1824b9ebb0cb931b99.js"></script>
<noscript>
Sorry, this page requires javascript!
</noscript>
</body>
</html>
尽管有所有这些解决方案,该应用程序仍会在所有经过测试的浏览器(FF、Chrome、Safari)中缓存 PWA 和。缓存只会在一次或多次重新加载后刷新 and/or 硬重新加载。
我还验证了捆绑文件散列已针对版本之间的更新代码进行了更改。
旧文件示例在代码更新和部署之前
5.bundle.aa1824b9ebb0cb931b99.js
新文件示例代码更新和部署之后
5.bundle.cae6d2bb162cbee138bc.js
index.html
中对捆绑文件的引用已使用新哈希更新,但浏览器仍会尝试获取旧文件 - 导致致命错误 "ChunkLoadError: Loading chunk [n.oldHash] failed."
。
我做错了吗?有没有其他方法可以强制浏览器(和 PWA)在新版本后刷新所有代码?
亲切的问候/K
有一个技巧可以通过为每个新版本添加一个获取参数来获取现金,如下所示:
<script src="/dist/5.bundle.aa1824b9ebb0cb931b99.js?v=2"></script>
并不是每次部署都必须更改 v 的值(您可以自动执行)
我按照 post 中提到的类似原则来清除我的缓存。我只是在 setInterval 上发出请求,而不是将应用程序包装在一个清晰的缓存 HOC 中。 https://dev.to/ammartinwala52/clear-cache-on-build-for-react-apps-1k8j the article this links to also has some good examples, it is worth looking at both. https://dev.to/flexdinesh/cache-busting-a-react-app-22lk
不确定这是否是最佳方法,但它对我有用
我的应用程序是用 Reac / Redux 编写的,并使用 Workbox 生成我的服务工作者。 这有效 - 我可以确认在 运行 "workbox inject:manifest".
时生成的服务工作者中的修订已更新但是,我注意到客户端在新版本发布后不会更新缓存,新代码只会在多次刷新后加载。对于每个版本,我都确认修订已更新。
到目前为止,我尝试强制浏览器在新版本发布后清除缓存的方法是:
- 在我的 ServiceWorker 中实现了 skipWaiting() - 正确显示更新警报
- 添加了缓存 headers 以禁用 serviceWorker.js 和 css 文件的缓存(见下文)
- 将 [contenthash] 添加到我在 Webpack 中的所有捆绑文件,并为每个版本相应地更新 index.html
缓存headers
<IfModule mod_headers.c>
Header unset ETag
<IfModule mod_alias.c>
# disable browser cache for serviceWorker.js file
<FilesMatch "^(serviceWorker.js)$">
Header unset Expires
Header set Cache-Control "max-age=0"
</FilesMatch>
<FilesMatch "\.(js|css)$">
# cache for 24 hours = 86400 seconds
Header set Cache-Control "max-age=86400, public, no-transform, must-revalidate"
</FilesMatch>
</IfModule>
</IfModule>
index.html
...
<body style="overflow: hidden">
<div id="app"></div>
<script src="/dist/main.bundle.aae6d2bb162cbee13899.js"></script>
<script src="/dist/0.bundle.aaa837f16bb646266d99.js"></script>
<script src="/dist/1.bundle.aa653fe9abbe232be599.js"></script>
<script src="/dist/2.bundle.aa3096daabb2d428a899.js"></script>
<script src="/dist/3.bundle.aa1650fc5bb4e1f1ea99.js"></script>
<script src="/dist/4.bundle.aae80e50cbb06d5e5599.js"></script>
<script src="/dist/5.bundle.aa1824b9ebb0cb931b99.js"></script>
<noscript>
Sorry, this page requires javascript!
</noscript>
</body>
</html>
尽管有所有这些解决方案,该应用程序仍会在所有经过测试的浏览器(FF、Chrome、Safari)中缓存 PWA 和。缓存只会在一次或多次重新加载后刷新 and/or 硬重新加载。
我还验证了捆绑文件散列已针对版本之间的更新代码进行了更改。
旧文件示例在代码更新和部署之前
5.bundle.aa1824b9ebb0cb931b99.js
新文件示例代码更新和部署之后
5.bundle.cae6d2bb162cbee138bc.js
index.html
中对捆绑文件的引用已使用新哈希更新,但浏览器仍会尝试获取旧文件 - 导致致命错误 "ChunkLoadError: Loading chunk [n.oldHash] failed."
。
我做错了吗?有没有其他方法可以强制浏览器(和 PWA)在新版本后刷新所有代码?
亲切的问候/K
有一个技巧可以通过为每个新版本添加一个获取参数来获取现金,如下所示:
<script src="/dist/5.bundle.aa1824b9ebb0cb931b99.js?v=2"></script>
并不是每次部署都必须更改 v 的值(您可以自动执行)
我按照 post 中提到的类似原则来清除我的缓存。我只是在 setInterval 上发出请求,而不是将应用程序包装在一个清晰的缓存 HOC 中。 https://dev.to/ammartinwala52/clear-cache-on-build-for-react-apps-1k8j the article this links to also has some good examples, it is worth looking at both. https://dev.to/flexdinesh/cache-busting-a-react-app-22lk
不确定这是否是最佳方法,但它对我有用