如何使用Create React App实现skipWaiting?

时间:2018-10-20 09:54:40

标签: reactjs service-worker create-react-app

我希望用户能够在有新服务人员可用时等待现场更新?当有新的更新可用时,我已经能够显示一个弹出窗口,但是我想添加一个按钮来当场强制更新。我知道可以通过调用skipWaiting来实现,但是不确定如何使用Create React App来实现它。有谁能做到这一点?希望能有所帮助。谢谢!

6 个答案:

答案 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)

skipWaitingclientsClaim已默认生成。

这是我自动更新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。而是等待用户刷新页面。 您可以使用消息传递基础结构来通知用户,以更新为例。