我正在尝试使用 Workbox 实施“缓存然后网络”策略。
我已将 Workbox 设置为使用staleWhileRevalidateruntimeCaching 处理程序,但我不确定如何最好地更新页面一次/如果我们从网络更新缓存。
文档说:
除了更新适当的缓存之外,它还将触发底层 RequestWrapper 中定义的任何适当的插件。
那有什么用吗?有没有使用 Workbox 完成此策略的示例(顺便说一句,这是一个很棒的工具,所以感谢它的维护者)?
我有一个 Webpack 配置文件,它使用webpack-pwa-manifest插件 ( https://github.com/arthurbergmz/webpack-pwa-manifest ) 生成 PWA 清单文件。清单文件名为manifest.hash.json,其中“hash”是在每次构建时动态生成的值。
我还使用(https://developers.google.com/web/tools/workbox/modules/workbox-webpack-pluginInjectManifest )插件来渲染预缓存清单,然后将其注入到服务工作线程文件中。Workbox
这是我的 Webpack 配置文件的“插件”部分:
plugins: [
new CleanWebpackPlugin([ path.join(destDir, '*.*') ], {
allowExternal: true,
exclude: [],
verbose: true,
dry: false
}),
new MiniCssExtractPlugin({
filename: 'style.[hash].css'
}),
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
template: path.join(projectRoot, 'src/index.html')
}),
new WebpackPwaManifest({
name: 'Test PWA',
short_name: 'Test PWA',
fingerprints: true,
inject: true,
lang: 'en-US',
start_url: 'https://localhost:8120/index.html',
display: 'standalone',
theme_color: '#777777',
background_color: '#333333',
icons: [
{
src: path.join(sourceDir, 'images/icon.png'),
sizes: …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Workbox.injectManifest 来生成一个 Service Worker,但是我的 Service Worker 的预缓存清单的路径没有正确生成。
我的 Webpackoutput.path是 'path.resolve('./scripts/app/dist')' 和我的 Workbox 配置:
new WorkboxPlugin.InjectManifest({
swSrc: path.resolve("./scripts/app/src/service-worker.js"),
swDest: "../../../sw.js",
globDirectory: path.resolve("./"),
globPatterns: [
"scripts/**/*.js",
"fonts/**/*.{eot,ttf,woff,woff2,otf}",
"images/**/*.{png,jpg,svg,gif,ico}",
"styles/**/*.css"
]
});
Run Code Online (Sandbox Code Playgroud)
因为默认情况下,Workbox 在 output.path 中创建 sw.js 并且我希望它在我网站的根目录中,../../../sw.js 但预缓存清单将保留在 output.path 中,这是./scripts/app/dist. 问题是在生成的 sw.js 中指向清单的路径是:
importScripts("precache-manifest.472387a6bbb5e3e8f5e8392d628202d5.js", "https://storage.googleapis.com/workbox-cdn/releases/3.1.0/workbox-sw.js");
Run Code Online (Sandbox Code Playgroud)
这是指向 sw.js 所在的位置,它位于站点根目录中,但无法找到。这是错误还是我没有正确配置?我曾尝试使用“importsDirectory”,但这只是将清单移动到另一个位置,而 sw.js 上的路径仍然是错误的。
更新
我的服务工作者模板中有这个:
workbox.skipWaiting();
workbox.clientsClaim();
workbox.precaching.precacheAndRoute([])
workbox.routing.registerRoute( .......
Run Code Online (Sandbox Code Playgroud)
但是当我构建时,不会填充数组并创建一个外部清单:这就是插件创建的内容:
importScripts("precache-manifest.aa4b439ba2589f9d3cf0c56e1b06323d.js", "https://storage.googleapis.com/workbox-cdn/releases/3.1.0/workbox-sw.js");
workbox.skipWaiting();
workbox.clientsClaim();
workbox.precaching.precacheAndRoute([])
workbox.routing.registerRoute(
Run Code Online (Sandbox Code Playgroud) 我的 service worker 安装在一个临时目录中
主要网站在: https:example.com
分期开启: https:example.com/test/
服务工作者路径: https:example.com/test/serviceworker.js
这是我注册服务工作者的方式:
navigator.serviceWorker.register('https:example.com/test/serviceworker.js', {scope: '/test/'})
.then(registration => {
console.log(`Service Worker registered! Scope: ${registration.scope}`);
})
Run Code Online (Sandbox Code Playgroud)
Service Worker 工作正常,并已安装。
我担心的是,在 serviceworker.js 中,我想使用/自动指向当前目录的路径,在这种情况下:/staging/
例如,当我想在临时站点中缓存主页时
/**
* Cache the homepage.
*/
workbox.routing.registerRoute('/', workbox.strategies.staleWhileRevalidate();
Run Code Online (Sandbox Code Playgroud)
这里的缓存https:example.com不是https:example.com/test/
我知道我可以简单地更改registerRoute('/')为registerRoute('/staging/)'
但这效率不高,并且会使我需要为 localhost、暂存和部署使用不同版本的 serviceworker。我想知道在此处执行此操作的正确方法是什么,因此我可以将范围“/”设置为 serviceworker.js 所在的当前目录。谢谢。
我已经使用 Workbox 库实现了一个服务工作者。对于网络推送通知,我们通过 WebPush ( https://github.com/web-push-libs/web-push-csharp )使用 FCM
现在我想要的是发送一个动态推送通知图标。图标以 base64 格式保存在数据库中。当我尝试使用 WebPush 从服务器端发送推送时,它会抛出异常:“错误请求”。
那么是否可以使用 Base64 而不是图像 URL?
在谷歌的开发者页面上,它提到“某些浏览器可能需要通过 HTTPS 提供图像”。那么,这是问题吗?
我尝试通过 webPush 将 base64 发送到 FCM。它没有用。
如果我用 base64 对图标进行硬编码,它就可以工作。
notificationData.icon = 'data:image/png;base64,iVBORw0KGg....'; //its working.
// PUSH NOTIFICATIONS Event
self.addEventListener('push', function(event) {
console.log('[Service Worker]: Received push event', event)
var notificationData = {}
if (event.data.json()) {
notificationData = event.data.json().notification // "notification node is specific for @angular/service-worker
} else {
notificationData = {
title: 'Notification',
message: 'You got notification',
icon: './assets/imgs/notificationicon.jpg' …Run Code Online (Sandbox Code Playgroud) service-worker web-push progressive-web-apps angular workbox
我的 window.js 中有这个...
const wb = new Workbox('sw.js');
wb.messageSW({type:'START'});
wb.addEventListener('message', e=>{
console.log(e);
});
Run Code Online (Sandbox Code Playgroud)
...在我的 sw.js 中,我有...
self.addEventListener('message', (e)=>{
if (e.data) {
switch(e.data.type) {
case 'START':
//do some processing here...
//...then how do I send a message to the client here so...
//...that it will be received by the wb.addEventListener('message',... in window.js?
break;
}
}
});
Run Code Online (Sandbox Code Playgroud)
我尝试通过 e.ports[0] 中的 MessagePort.postMessage() 发送,但它不起作用。我觉得这是一些基本的东西,特别是使用 Workbox 类,但我就是无法让它工作。
我的最后一招是使用 BroadcastChannel (带有填充),但我首先尝试这个,因为它可能不需要任何填充即可工作。
在生成的precache-manifest.*.js文件中,当我需要绝对路径时,URL 都引用相对路径,因为我的应用程序也会有一些子目录。
生成文件的示例:
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "1d94d834b7044ec6d4e9",
"url": "js/app.js"
},
{
"revision": "632f09e6ed606bbed1f1",
"url": "css/app.css"
},
...
}
Run Code Online (Sandbox Code Playgroud)
当我需要它看起来像这样时:
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "1d94d834b7044ec6d4e9",
"url": "/js/app.js"
},
{
"revision": "632f09e6ed606bbed1f1",
"url": "/css/app.css"
},
...
}
Run Code Online (Sandbox Code Playgroud)
我正在使用webpack4.41.0 并且workbox-webpack-plugin4.3.1
任何帮助将不胜感激!如果需要的话我也可以添加更多细节。
这是我的 webpack 配置:
let config = {
entry,
stats: {
hash: false,
version: false,
timings: false,
children: false,
errorDetails: false,
entrypoints: false,
performance: inProduction,
chunks: false,
modules: false,
reasons: …Run Code Online (Sandbox Code Playgroud) service-worker progressive-web-apps workbox workbox-webpack-plugin
我已经实现了 Workbox 来使用 webpack 生成我的 Service Worker。这工作得很好 - 我可以确认revision运行时生成的服务工作线程中已更新yarn run generate-sw(package.json "generate-sw": "workbox inject:manifest":)。
问题是 - 我注意到我的客户在新版本发布后没有更新缓存。即使在更新服务工作线程数天后,我的客户端仍在缓存旧代码,而新代码仅在多次刷新和/或取消注册服务工作线程后才会缓存。对于每个版本const CACHE_DYNAMIC_NAME = 'dynamic-v1.1.0'都会更新。
如何确保客户端在新版本发布后立即更新缓存?
serviceWorker-base.js
importScripts('workbox-sw.prod.v2.1.3.js')
const CACHE_DYNAMIC_NAME = 'dynamic-v1.1.0'
const workboxSW = new self.WorkboxSW()
// Cache then network for fonts
workboxSW.router.registerRoute(
/.*(?:googleapis)\.com.*$/,
workboxSW.strategies.staleWhileRevalidate({
cacheName: 'google-font',
cacheExpiration: {
maxEntries: 1,
maxAgeSeconds: 60 * 60 * 24 * 28
}
})
)
// Cache then network for css
workboxSW.router.registerRoute(
'/dist/main.css',
workboxSW.strategies.staleWhileRevalidate({
cacheName: 'css'
})
)
// Cache …Run Code Online (Sandbox Code Playgroud) 我已经用 CRA 创建了 React 应用程序。我想要定制软件。我正在使用workbox-build 和injectManifest 来创建我的SW。但我仍然坚持等待激活 =/ 和 Uncaught SyntaxError: Unexpected token '<'。或者..
如果我使用 sw-template2.js .. 我可以跳过等待.. 但我仍然收到 Uncaught SyntaxError: Unexpected token '<' 和白页,我需要手动刷新页面才能查看内容。有什么建议如何使用该软件顺利更新我的页面吗?
我的registerServiceWorker.js:
// In production, we register a service worker to serve assets from local cache.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on the "N+1" visit to a page, since …Run Code Online (Sandbox Code Playgroud) 我使用的是 Nuxtjs 2.15.7,最近在我的控制台中收到此错误
当我搜索时,只需要@nuxt/pwa 发布. 但我的项目中没有pwa模块!
这是我的 package.json
{
"name": "my-app",
"version": "2.0.0",
"private": true,
"scripts": {
"dev": "nuxt",
"dev:host": "nuxt --hostname 0.0.0.0 --port 8000",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate"
},
"dependencies": {
"@nuxtjs/auth": "^4.9.1",
"@nuxtjs/axios": "^5.13.1",
"@nuxtjs/device": "^2.1.0",
"@nuxtjs/google-gtag": "^1.0.4",
"@nuxtjs/gtm": "^2.4.0",
"cookie-universal-nuxt": "^2.1.4",
"core-js": "^3.15.1",
"nuxt": "^2.15.7",
"swiper": "^5.4.5",
"v-viewer": "^1.5.1",
"vee-validate": "^3.3.7",
"vue-awesome-swiper": "^4.1.1",
"vue-cropperjs": "^4.1.0",
"vue-easy-dnd": "^1.12.2",
"vue-persian-datetime-picker": "^2.2.0",
"vue-product-zoomer": "^3.0.1",
"vue-sweetalert2": "^4.2.1",
"vue2-editor": "^2.10.2",
"vuedraggable": "^2.24.0"
},
"devDependencies": { …Run Code Online (Sandbox Code Playgroud) workbox ×10
javascript ×3
webpack ×2
angular ×1
caching ×1
nuxt.js ×1
reactjs ×1
vue.js ×1
web-push ×1
web-worker ×1