【问题标题】:workbox-webpack-plugin & Angular. How to listen to broadcastUpdate event in Angular工作箱-webpack-plugin 和 Angular。如何在 Angular 中收听广播更新事件
【发布时间】:2019-01-10 10:12:24
【问题描述】:

我正在尝试将 service-worker 与我的 Angular 应用程序一起使用。它是使用 webpack 构建的。

我使用 workbox-webpack-plugin。我想为我的 GET API 调用提供缓存服务,并在后台更新数据。

为此,我使用选项 runtimeCaching 和处理程序 staleWhileRevalidate (more details on GenerateSW plugin here)

这是我在 webpack.config.js 中的配置:

  new GenerateSW({
    // importWorkboxFrom: 'local',
    clientsClaim: true,
    skipWaiting: true,
    navigateFallback: '/index.html',
    runtimeCaching: [
      {
        // Match any same-origin request that contains 'api'.
        urlPattern: /https:\/\/api.*/,
        handler: 'staleWhileRevalidate',
        options: {
          cacheName: 'api',
          broadcastUpdate: {
            channelName: 'api-updates',
          },
          // Add in any additional plugin logic you need.
          plugins: [],
        },
      }
    ]
  }),

根据this documentation,我应该能够在缓存更新时收到一个事件(我想向用户显示一些东西,以便他可以刷新数据)。

接收数据的代码如下所示:

export class AppComponent implements OnInit {

  public ngOnInit() {
    console.log( 'AppComponent - ngOnInit' );

    const updatesChannel = new BroadcastChannel('api-updates');
    updatesChannel.addEventListener('message', async (event) => {
      console.log('Event received');
    });
  }
}

我将此代码放在我的一个 Angular 组件中,即使我确定缓存已更新,它也从未被调用过。

我认为这可能与更改检测在 Angular (like described in this question) 中的工作方式有关,但我不确定如何修复它。

有人设法成功收听来自 Angular 组件的广播事件吗?

【问题讨论】:

    标签: angular webpack broadcast workbox workbox-webpack-plugin


    【解决方案1】:

    很难通过工作箱文档找到解决方案。

    在您的应用启动时,您可以注册到 workbox serviceworker 并覆盖 onupdatefound 在检测到更改并加载它时更新 UI:

    if (process.env.NODE_ENV != "development" && "serviceWorker" in navigator) {
      window.addEventListener("load", () => {
        navigator.serviceWorker
          .register("/service-worker.js")
          .then(registration => {
            registration.onupdatefound = event => {
              console.log("An update has been detected. Workbox will now download the newest version, then send a notification.");
            };
          })
          .catch(registrationError => {
            console.log("SW registration failed: ", registrationError);
          });
      });
    }
    

    当工作箱检测到当前缓存版本与存储在服务器上的版本之间存在差异时触发此事件(在precache-manifest.d6104197c4431d9f111e4c4f0bdf858d.js 中存储为哈希)。

    为了检测接收到并准备加载的文件的实际更新,我无法按照文档中的描述设置broadcastUpdate 选项,因此受到它的启发,我在 webpack 和我的应用程序之间实现了一个 MessageChannel。

    在 webpack 中:

    new WorkboxPlugin.GenerateSW({
          // these options encourage the ServiceWorkers to get in there fast
          // and not allow any straggling 'old' SWs to hang around
          clientsClaim: true,
          skipWaiting: true,
          include: [
            /\.html$/,
            /\.js$/,
            /\.jpg$/,
            /\.svg$/,
            /\.png$/,
            /\.json$/,
            /\.xml$/
          ],
          runtimeCaching: [
            {
              urlPattern: /./,
              handler: "StaleWhileRevalidate",
              options: {
                // Add in any additional plugin logic you need.
                plugins: [
                  {
                    cacheDidUpdate: event => {
                      clients.matchAll().then(clients => {
                        clients.forEach(client => {
                          var msg_chan = new MessageChannel();
                          client.postMessage("APP_UPDATE", [msg_chan.port2]);
                        });
                      });
                    }
                  }
                ]
              }
            }
          ]
        })
    

    这会将消息从我不知道从哪里发送到频道。然后我们可以在应用中的该频道上添加一个监听器来触发 ou UI。

    应用内:

    if ("serviceWorker" in navigator) {
      navigator.serviceWorker.addEventListener("message", event => {
        if (event.data == "APP_UPDATE") {
          dispatch(AppActions.cacheDidUpdate());
        }
      });
    }
    

    【讨论】:

    • ❗️ Juste 在实际更新之前意识到onupdatefound 触发,这可能需要更多时间,所以最好找到其他选项?。
    • Safari 目前不支持广播频道?。
    • 刚刚使用 MessageChannel 编辑过,适用于 Safari developer.mozilla.org/en-US/docs/Web/API/MessageChannel
    猜你喜欢
    • 2023-02-09
    • 2016-01-25
    • 1970-01-01
    • 2015-04-12
    • 2022-07-05
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多