workbox-webpack-plugin & Angular。如何在 Angular 中收听 broadcastUpdate 事件
workbox-webpack-plugin & Angular. How to listen to broadcastUpdate event in Angular
我正尝试在我的 Angular 应用程序中使用 service-worker。它是使用 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 () 中更改检测的工作方式有关,但我不确定如何修复它。
有没有人设法成功收听来自 Angular 组件的广播事件?
很难找到工作箱文档的解决方案。
在您的应用程序启动时,您可以注册到 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());
}
});
}
我正尝试在我的 Angular 应用程序中使用 service-worker。它是使用 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 (
有没有人设法成功收听来自 Angular 组件的广播事件?
很难找到工作箱文档的解决方案。
在您的应用程序启动时,您可以注册到 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());
}
});
}