如何使用 Create React App 实现 skipWaiting?
How to implement skipWaiting with Create React App?
我希望用户能够在新的 Service Worker 可用并等待时立即更新?当有新更新可用时,我已经能够显示弹出窗口,但我想添加一个按钮以强制当场更新。我知道这可以通过调用 skipWaiting 来实现,但不确定如何使用 Create React App 来实现它。有没有人能够做到这一点?非常感谢您的帮助。谢谢!
我使用了一个名为 https://github.com/bbhlondon/cra-append-sw 的包来附加以下代码来调用触发器 skipWaiting:
self.addEventListener('message', event => {
if (event.data === 'skipWaiting') {
self.skipWaiting();
}
});
@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",
在serviceWorker.js文件中可以找到这段代码
if (config && config.onUpdate) {
config.onUpdate(registration);
}
所以实现 config.onUpdate 功能
创建文件swConfig.js
export default {
onUpdate: registration => {
registration.unregister().then(() => {
window.location.reload()
})
},
onSuccess: registration => {
console.info('service worker on success state')
console.log(registration)
},
}
在index.js将实现函数发送给serviceWorker
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import swConfig from './swConfig'
ReactDOM.render(<App />,
document.getElementById('root'));
serviceWorker.register(swConfig);
查看此回购协议
https://github.com/wgod58/create_react_app_pwaupdate
我知道它已经得到解答,但我找到了一个解决方案,当然除了 workbox 之外不需要任何其他包。
在 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();
。
CRA build\service-worker.js
文件现在(v3 plus)包含处理 skipWaiting
:
的代码
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
在 index.js
中调用的注册函数 serviceWorker.js
文件现在接受配置参数:
serviceWorker.register({
onUpdate: registration => {
const waitingServiceWorker = registration.waiting
if (waitingServiceWorker) {
waitingServiceWorker.addEventListener("statechange", event => {
if (event.target.state === "activated") {
window.location.reload()
}
});
waitingServiceWorker.postMessage({ type: "SKIP_WAITING" });
}
}
});
这将跳过等待,然后在应用更新后刷新页面。
您应该在 service worker 的安装事件中调用 skipWaiting 方法。
Service Worker 与 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
}
此外:如果您需要将缓存资产与活动同步,请不要调用 skipWaiting UI。如果您的 service worker 正在更新并且可能会破坏 UI 那么请不要调用 skipWaiting。而是等待用户刷新页面。
您可以使用消息传递基础结构来通知用户有更新可用,例如让他们刷新。
我希望用户能够在新的 Service Worker 可用并等待时立即更新?当有新更新可用时,我已经能够显示弹出窗口,但我想添加一个按钮以强制当场更新。我知道这可以通过调用 skipWaiting 来实现,但不确定如何使用 Create React App 来实现它。有没有人能够做到这一点?非常感谢您的帮助。谢谢!
我使用了一个名为 https://github.com/bbhlondon/cra-append-sw 的包来附加以下代码来调用触发器 skipWaiting:
self.addEventListener('message', event => {
if (event.data === 'skipWaiting') {
self.skipWaiting();
}
});
@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",
在serviceWorker.js文件中可以找到这段代码
if (config && config.onUpdate) {
config.onUpdate(registration);
}
所以实现 config.onUpdate 功能
创建文件swConfig.js
export default {
onUpdate: registration => {
registration.unregister().then(() => {
window.location.reload()
})
},
onSuccess: registration => {
console.info('service worker on success state')
console.log(registration)
},
}
在index.js将实现函数发送给serviceWorker
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import swConfig from './swConfig'
ReactDOM.render(<App />,
document.getElementById('root'));
serviceWorker.register(swConfig);
查看此回购协议 https://github.com/wgod58/create_react_app_pwaupdate
我知道它已经得到解答,但我找到了一个解决方案,当然除了 workbox 之外不需要任何其他包。
在 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();
。
CRA build\service-worker.js
文件现在(v3 plus)包含处理 skipWaiting
:
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
});
在 index.js
中调用的注册函数 serviceWorker.js
文件现在接受配置参数:
serviceWorker.register({
onUpdate: registration => {
const waitingServiceWorker = registration.waiting
if (waitingServiceWorker) {
waitingServiceWorker.addEventListener("statechange", event => {
if (event.target.state === "activated") {
window.location.reload()
}
});
waitingServiceWorker.postMessage({ type: "SKIP_WAITING" });
}
}
});
这将跳过等待,然后在应用更新后刷新页面。
您应该在 service worker 的安装事件中调用 skipWaiting 方法。 Service Worker 与 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
}
此外:如果您需要将缓存资产与活动同步,请不要调用 skipWaiting UI。如果您的 service worker 正在更新并且可能会破坏 UI 那么请不要调用 skipWaiting。而是等待用户刷新页面。 您可以使用消息传递基础结构来通知用户有更新可用,例如让他们刷新。