Serviceworker 永远不会被激活或接收消息,但工作箱功能适用于子路径
Serviceworker never gets activated or receives messages but workbox functionality works on subpaths
在我当前使用带有 (workbox-webpack-plugin
) 和 workbox (带有 workbox-window
) 的 webpack 的项目中,我遇到了一个错误,当页面以 "deep url",如“/my-path/is-nested”。
它将在“/我的路径”上工作。
在最小的可重现环境中,这应该会发生。
- 在新标签页中访问应用程序(例如通过
https://my-app.my-name.company-dev-envs.cloud/some-unique-id
)
- ServiceWorker 通过工作箱注册 (
.register()
)
- 注册后,
messageSW
用于索取SW"version"
- ServiceWorker 使用
event.ports[0].postMessage
和一个指示版本的字符串进行响应
是否在 "deep" 路径中访问站点,如 /some-unique-id/test,消息将永远无法工作。
Workbox 成功 "register" - 但不会触发任何事件(除了 externalactivated
当 Update on Reload
在 Application > Service Worker 选项卡中被选中时)
该 serviceworker 将被报告为 "active and running",而不会显示其他服务人员。它似乎也可以处理提取。只有消息和事件永远不会 respond/fire 通过 wb
Workbox Window 实例。
"application" 选项卡报告服务工作者处于活动状态并且 运行:
index.js(申请的主要入口)
/* globals window, System */
import './offline';
// [...]
offline.js
import { Workbox } from 'workbox-window';
if ('serviceWorker' in navigator) {
const wb = new Workbox('./sw.js');
const attachDebugEventHandlers = (events) => {
events.forEach((eventName) => {
wb.addEventListener(eventName, () => {
console.log(`[workbox sw] ${eventName} triggered`);
});
});
};
attachDebugEventHandlers([
'activated',
'controlling',
'externalactivated',
'externalinstalling',
'externalwaiting',
'installed',
'message',
'redundant',
'waiting',
]);
wb.register()
.then((registration) => {
console.log('workbox sw register successful');
console.log("sending message")
wb.messageSW({ type: 'GET_VERSION' }).then((ver) => console.log(`[workbox sw] version reported as ${ver}`))
})
.catch((err) => {
console.error('[workbox sw] could not activate sw', err);
});
sw.js
const SW_VERSION = '1.0.0';
console.log("sw loaded")
import {createHandlerBoundToURL, precacheAndRoute} from 'workbox-precaching';
import { NavigationRoute, registerRoute } from 'workbox-routing'
// auto generate from webpack manifest
precacheAndRoute(self.__WB_MANIFEST, {
// Ignore all URL parameters.
ignoreURLParametersMatching: [/.*/] // main.js is loaded with a version hash
});
self.addEventListener('message', event => {
console.log(`[Message] event: `, event.data);
});
self.addEventListener('install', function(event) {
event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', (event) => {
event.waitUntil(self.clients.claim())
})
addEventListener('message', (event) => {
console.log("message")
if (event.data && event.data.type) {
if (event.data.type === 'GET_VERSION') {
event.ports[0].postMessage(SW_VERSION);
}
}
})
const handler = createHandlerBoundToURL('/index.html');
const navigationRoute = new NavigationRoute(handler);
registerRoute(navigationRoute);
webpack.config.js(为简洁起见缩短)
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = {
devtool: 'eval-source-map',
module: {
rules: [
{
test: /\.(jsx?)$/,
include: [
path.resolve(__dirname, 'src'),
],
use: ['babel-loader'],
},
// [...] (style loading)
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
},
],
},
],
},
devServer: {
historyApiFallback: true,
disableHostCheck: true
},
plugins: [
// [...]
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/html/index.html')
}),
// [...]
new WorkboxPlugin.InjectManifest({
swSrc: './src/sw.js',
swDest: 'sw.js',
maximumFileSizeToCacheInBytes: 12 * 1024 * 1024,
}),
],
};
使用的版本:
"webpack": "^4.33.0",
"webpack-cli": "^3.3.2",
"workbox-window": "^5.1.3"
"workbox-webpack-plugin": "^5.1.3"
我自己解决了。问题当然是当用户导航到子路径时 ./sw.js
的路径不正确。
https://my-website.com/a-subpath/a-resource
不会将 ./sw.js
解析为 https://my-website.com/sw.js
而是解析为 https://my-website.com/a-subpath/sw.js
这是一个非常愚蠢的错误,但希望有人能得到这个答案的帮助。如果 workbox-window
没有像注册成功一样正确解析,但拒绝了 ./sw.js
路径,也许会有所帮助。
在我当前使用带有 (workbox-webpack-plugin
) 和 workbox (带有 workbox-window
) 的 webpack 的项目中,我遇到了一个错误,当页面以 "deep url",如“/my-path/is-nested”。
它将在“/我的路径”上工作。
在最小的可重现环境中,这应该会发生。
- 在新标签页中访问应用程序(例如通过
https://my-app.my-name.company-dev-envs.cloud/some-unique-id
) - ServiceWorker 通过工作箱注册 (
.register()
) - 注册后,
messageSW
用于索取SW"version" - ServiceWorker 使用
event.ports[0].postMessage
和一个指示版本的字符串进行响应
是否在 "deep" 路径中访问站点,如 /some-unique-id/test,消息将永远无法工作。
Workbox 成功 "register" - 但不会触发任何事件(除了 externalactivated
当 Update on Reload
在 Application > Service Worker 选项卡中被选中时)
该 serviceworker 将被报告为 "active and running",而不会显示其他服务人员。它似乎也可以处理提取。只有消息和事件永远不会 respond/fire 通过 wb
Workbox Window 实例。
"application" 选项卡报告服务工作者处于活动状态并且 运行:
index.js(申请的主要入口)
/* globals window, System */
import './offline';
// [...]
offline.js
import { Workbox } from 'workbox-window';
if ('serviceWorker' in navigator) {
const wb = new Workbox('./sw.js');
const attachDebugEventHandlers = (events) => {
events.forEach((eventName) => {
wb.addEventListener(eventName, () => {
console.log(`[workbox sw] ${eventName} triggered`);
});
});
};
attachDebugEventHandlers([
'activated',
'controlling',
'externalactivated',
'externalinstalling',
'externalwaiting',
'installed',
'message',
'redundant',
'waiting',
]);
wb.register()
.then((registration) => {
console.log('workbox sw register successful');
console.log("sending message")
wb.messageSW({ type: 'GET_VERSION' }).then((ver) => console.log(`[workbox sw] version reported as ${ver}`))
})
.catch((err) => {
console.error('[workbox sw] could not activate sw', err);
});
sw.js
const SW_VERSION = '1.0.0';
console.log("sw loaded")
import {createHandlerBoundToURL, precacheAndRoute} from 'workbox-precaching';
import { NavigationRoute, registerRoute } from 'workbox-routing'
// auto generate from webpack manifest
precacheAndRoute(self.__WB_MANIFEST, {
// Ignore all URL parameters.
ignoreURLParametersMatching: [/.*/] // main.js is loaded with a version hash
});
self.addEventListener('message', event => {
console.log(`[Message] event: `, event.data);
});
self.addEventListener('install', function(event) {
event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', (event) => {
event.waitUntil(self.clients.claim())
})
addEventListener('message', (event) => {
console.log("message")
if (event.data && event.data.type) {
if (event.data.type === 'GET_VERSION') {
event.ports[0].postMessage(SW_VERSION);
}
}
})
const handler = createHandlerBoundToURL('/index.html');
const navigationRoute = new NavigationRoute(handler);
registerRoute(navigationRoute);
webpack.config.js(为简洁起见缩短)
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = {
devtool: 'eval-source-map',
module: {
rules: [
{
test: /\.(jsx?)$/,
include: [
path.resolve(__dirname, 'src'),
],
use: ['babel-loader'],
},
// [...] (style loading)
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
},
],
},
],
},
devServer: {
historyApiFallback: true,
disableHostCheck: true
},
plugins: [
// [...]
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/html/index.html')
}),
// [...]
new WorkboxPlugin.InjectManifest({
swSrc: './src/sw.js',
swDest: 'sw.js',
maximumFileSizeToCacheInBytes: 12 * 1024 * 1024,
}),
],
};
使用的版本:
"webpack": "^4.33.0",
"webpack-cli": "^3.3.2",
"workbox-window": "^5.1.3"
"workbox-webpack-plugin": "^5.1.3"
我自己解决了。问题当然是当用户导航到子路径时 ./sw.js
的路径不正确。
https://my-website.com/a-subpath/a-resource
不会将 ./sw.js
解析为 https://my-website.com/sw.js
而是解析为 https://my-website.com/a-subpath/sw.js
这是一个非常愚蠢的错误,但希望有人能得到这个答案的帮助。如果 workbox-window
没有像注册成功一样正确解析,但拒绝了 ./sw.js
路径,也许会有所帮助。