我希望用户能够在有新服务人员可用时等待现场更新?当有新的更新可用时,我已经能够显示一个弹出窗口,但是我想添加一个按钮来当场强制更新。我知道可以通过调用skipWaiting来实现,但是不确定如何使用Create React App来实现它。有谁能做到这一点?希望能有所帮助。谢谢!
答案 0 :(得分:1)
我使用了名为https://github.com/bbhlondon/cra-append-sw的程序包来附加以下代码以调用触发器skipWaiting:
self.addEventListener('message', event => {
if (event.data === 'skipWaiting') {
self.skipWaiting();
}
});
答案 1 :(得分:1)
@ user10532439的答案对我不起作用。我最终使用了https://github.com/bbhlondon/cra-append-sw 并添加
// @ts-ignore
workbox.skipWaiting();
// @ts-ignore
workbox.clientsClaim();
以及
"build": "react-scripts build && cra-append-sw -s ./src/custom-sw.js",
答案 2 :(得分:1)
skipWaiting
和clientsClaim
已默认生成。
这是我自动更新create_react_app_pwaupdate
的方式我在serviceWorker.js中使用window.location.reload()
和
self.addEventListener('install', event => {
self.skipWaiting();
//event.waitUntil(
// caching etc
//);
});
在custom-sw.js中
检查src \ custom-sw.js和src \ serviceWorker.js
答案 3 :(得分:0)
我知道已经回答了,但是我找到了一个解决方案,除了工作箱外,不需要任何其他软件包。
在 package.json 处:
"build": "react-scripts build && node ./src/serviceWorkerBuild"
serviceWorkerBuild.js
const workboxBuild = require('workbox-build');
// NOTE: This should be run *AFTER* all your assets are built
const buildSW = () => {
// This will return a Promise
return workboxBuild.injectManifest({
swSrc: 'src/serviceWorkerRules.js',
swDest: 'build/sw.js',
globDirectory: 'build',
globPatterns: [
'**\/*.{js,css,html,png}',
]
}).then(({count, size, warnings}) => {
// Optionally, log any warnings and details.
warnings.forEach(console.warn);
console.log(`${count} files will be precached, totaling ${size} bytes.`);
});
};
buildSW();
和 serviceWorkerRules.js ,您可以在其中添加规则:
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/3.5.0/workbox-sw.js'
);
/* global workbox */
if (workbox) {
console.log('Workbox is loaded');
self.addEventListener('install', event => {
self.skipWaiting();
});
/* injection point for manifest files. */
workbox.precaching.precacheAndRoute([]);
/* custom cache rules*/
workbox.routing.registerNavigationRoute('/index.html', {
blacklist: [/^\/_/, /\/[^\/]+\.[^\/]+$/],
});
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
workbox.strategies.cacheFirst({
cacheName: 'images',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: 5 * 24 * 60 * 60, // 5 Days
}),
],
}),
);
还在第78行的 serviceWorker.js 中添加window.location.reload();
。
答案 4 :(得分:0)
现在的CRA build\service-worker.js
文件(v3及更高版本)包含处理skipWaiting
的代码:
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
在serviceWorker.js
中调用的注册函数index.js
文件现在接受配置参数。您可以提供onUpdate
函数来检查正在等待服务的工作人员,致电skipWaiting()
,然后重新加载页面。
答案 5 :(得分:0)
您应该在服务工作者的install事件中调用skipWaiting方法。 服务工作人员已与UI / React代码分离。因此,真的与反应无关。
现在,我有一个模式将安装事件代码重构为其自己的方法,因此我的服务工作者通常看起来像这样:
self.addEventListener( "install", function ( event ) {
event.waitUntil( installServiceWorker() );
} );
function installServiceWorker() {
self.skipWaiting();
// do stuff here like pre-caching site core assets
//most likely returning a promise
}
也:如果您需要将缓存的资产与活动UI同步,请不要调用skipWaiting。如果您的服务人员正在更新,并且可能会破坏UI,请不要调用skipWaiting。而是等待用户刷新页面。 您可以使用消息传递基础结构来通知用户,以更新为例。