Angular v10 Service Worker 官方更新方法不起作用
Angular v10 Service Worker Official Update Methodology Doesn't Work
编辑摘要:我创建了一个最小的 reproducible example
我不再认为这与 css 或与此相关的任何 @font-face
声明有关。问题在于 swUpdate.checkForUpdate()
的官方 Angular 方式可能与 appRef.isStable
订阅结合使用。
我认为现在正在发生的事情是 angular 提供的 swUpdate 服务误认为存在实际更新,即使缓存内容的散列值保持不变。
我通过将 angular.json
文件中的所有 css 文件更改为如下所示来解决这个问题:
{
"input": "node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"bundleName": "material-theme",
"inject": false
}
然后我做了一个简单的服务,将捆绑的样式表添加到我的 header。我可以在任何时间点添加它们,甚至可以选择在应用程序加载几分钟后添加它们(下面的 swUpdate 事件多次触发)。
const appIsStable$ = this.appRef.isStable.pipe(takeWhile(isStable => isStable === true));
const everyMinute$ = interval(60*1000);
const swUpdateCheck$ = concat(appIsStable$, everyMinute$);
swUpdateCheck$.subscribe(() => {
console.log('update check');
this.swUpdate.checkForUpdate().then(() => {
console.log('new version available');
if(this.window.confirm('New version available. Click OK to download')){
this.swUpdate.activateUpdate().then(() => {
this.window.location.reload();
});
}
}, (rej) => {
debugger;
});
});
它仍然提示我更新应用程序。
关于这个我读到了两件事 -
- Devtools 实际上可能会破坏 service worker 运行s cache-busting.
的自然循环
- Angular 建议您通过
checkForUpdates()
订阅他们的可观察事件并使用 app.isStable
事件多次触发的方式。
我创建了一个最小的 reproducible example 并且确实确认主要更新问题在于 Angular 官方文档中的更新方法检查。
简单地 npm install
然后 运行 一个 http-server 像这样的来自 dist 文件夹的实例
http-server -p 4200 -c-1 ./sw-css-test
你会明白我的意思的!
原版Post:
问题 - 在没有物理更改任何文件的情况下,服务人员认为有更新需要出去获取。
情况:使用 Angular 10 配置软件可用。导入多个库如Angular Material等
理论:Angular material 尝试获取 Google 字体 'Roboto'(如果在本地文件树中找不到),如下所述我捆绑的 style.css 文件中的片段。因为它使用 url() 函数作为回退,所以它会在缓存中查找并找到它,如 service worker 的 304 响应所示,未修改。但是,由于 style.css 文件发生了变化(大概是因为它找到了字体?),它返回了 200 响应。然后这会提示 service worker 的缓存破坏,它认为有更新需要出去获取。
一旦你获得更新,冲洗、清洗、重复,你就有了一个无限的更新循环。当您的应用程序有实际更新时他们应该去下载,这对于尝试提示用户是不利的。为什么会这样?
以下内容是从 css.
捆绑包中截取的
@font-face {
font-family: Roboto;
font-style: normal;
font-weight: 400;
src: local("Roboto"),local("Roboto-Regular"),url(roboto-v20-latin-ext_latin-regular.5cb5c8f08bb4e6cb64c3.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-regular.ae804dc012b1b5255474.woff) format("woff")
}
@font-face {
font-family: Roboto;
font-style: normal;
font-weight: 500;
src: local("Roboto Medium"),local("Roboto-Medium"),url(roboto-v20-latin-ext_latin-500.0b45721325446d537b54.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-500.e492ac63197a57e7f4d3.woff) format("woff")
}
@font-face {
font-family: Roboto;
font-style: normal;
font-weight: 700;
src: local("Roboto Bold"),local("Roboto-Bold"),url(roboto-v20-latin-ext_latin-700.1d1ef7788f0ff084b881.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-700.8aba6dc5d991e4367d7a.woff) format("woff")
}
“网络”选项卡中的代码段
我的思路是否正确?
建议的解决方案:找出一种方法让 material 库引用 Roboto 的静态版本。
还有其他更好的解决方案吗?
参考我的ngsw-config.json:
{
"$schema": "../node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/manifest.webmanifest",
"/*.css",
"/*.js"
]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
]
}
}
]
}
注意:我已尝试从服务工作者中删除所有 css 文件和 ttf、woff 和 woff2 资产。然而它仍然带着更新回来。
非常感谢任何帮助。谢谢。
您是否尝试过查看 v10 specific documentation 并检查以确保它按照您上面的描述正常工作?
看起来无论有没有更新,承诺总是会解决。尝试将 available
observable 与 checkForUpdate()
?
结合使用
另外,尝试从 ngsw-config.json
中提取您的清单文件,看看是否也有帮助。我以前在该文件中看到过哈希不匹配。
在你的 config.url 之后 ngsw/state
的输出是什么?
编辑摘要:我创建了一个最小的 reproducible example
我不再认为这与 css 或与此相关的任何 @font-face
声明有关。问题在于 swUpdate.checkForUpdate()
的官方 Angular 方式可能与 appRef.isStable
订阅结合使用。
我认为现在正在发生的事情是 angular 提供的 swUpdate 服务误认为存在实际更新,即使缓存内容的散列值保持不变。
我通过将 angular.json
文件中的所有 css 文件更改为如下所示来解决这个问题:
{
"input": "node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"bundleName": "material-theme",
"inject": false
}
然后我做了一个简单的服务,将捆绑的样式表添加到我的 header。我可以在任何时间点添加它们,甚至可以选择在应用程序加载几分钟后添加它们(下面的 swUpdate 事件多次触发)。
const appIsStable$ = this.appRef.isStable.pipe(takeWhile(isStable => isStable === true));
const everyMinute$ = interval(60*1000);
const swUpdateCheck$ = concat(appIsStable$, everyMinute$);
swUpdateCheck$.subscribe(() => {
console.log('update check');
this.swUpdate.checkForUpdate().then(() => {
console.log('new version available');
if(this.window.confirm('New version available. Click OK to download')){
this.swUpdate.activateUpdate().then(() => {
this.window.location.reload();
});
}
}, (rej) => {
debugger;
});
});
它仍然提示我更新应用程序。
关于这个我读到了两件事 -
- Devtools 实际上可能会破坏 service worker 运行s cache-busting. 的自然循环
- Angular 建议您通过
checkForUpdates()
订阅他们的可观察事件并使用app.isStable
事件多次触发的方式。
我创建了一个最小的 reproducible example 并且确实确认主要更新问题在于 Angular 官方文档中的更新方法检查。
简单地 npm install
然后 运行 一个 http-server 像这样的来自 dist 文件夹的实例
http-server -p 4200 -c-1 ./sw-css-test
你会明白我的意思的!
原版Post:
问题 - 在没有物理更改任何文件的情况下,服务人员认为有更新需要出去获取。
情况:使用 Angular 10 配置软件可用。导入多个库如Angular Material等
理论:Angular material 尝试获取 Google 字体 'Roboto'(如果在本地文件树中找不到),如下所述我捆绑的 style.css 文件中的片段。因为它使用 url() 函数作为回退,所以它会在缓存中查找并找到它,如 service worker 的 304 响应所示,未修改。但是,由于 style.css 文件发生了变化(大概是因为它找到了字体?),它返回了 200 响应。然后这会提示 service worker 的缓存破坏,它认为有更新需要出去获取。
一旦你获得更新,冲洗、清洗、重复,你就有了一个无限的更新循环。当您的应用程序有实际更新时他们应该去下载,这对于尝试提示用户是不利的。为什么会这样?
以下内容是从 css.
捆绑包中截取的@font-face {
font-family: Roboto;
font-style: normal;
font-weight: 400;
src: local("Roboto"),local("Roboto-Regular"),url(roboto-v20-latin-ext_latin-regular.5cb5c8f08bb4e6cb64c3.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-regular.ae804dc012b1b5255474.woff) format("woff")
}
@font-face {
font-family: Roboto;
font-style: normal;
font-weight: 500;
src: local("Roboto Medium"),local("Roboto-Medium"),url(roboto-v20-latin-ext_latin-500.0b45721325446d537b54.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-500.e492ac63197a57e7f4d3.woff) format("woff")
}
@font-face {
font-family: Roboto;
font-style: normal;
font-weight: 700;
src: local("Roboto Bold"),local("Roboto-Bold"),url(roboto-v20-latin-ext_latin-700.1d1ef7788f0ff084b881.woff2) format("woff2"),url(roboto-v20-latin-ext_latin-700.8aba6dc5d991e4367d7a.woff) format("woff")
}
“网络”选项卡中的代码段
我的思路是否正确?
建议的解决方案:找出一种方法让 material 库引用 Roboto 的静态版本。
还有其他更好的解决方案吗?
参考我的ngsw-config.json:
{
"$schema": "../node_modules/@angular/service-worker/config/schema.json",
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/manifest.webmanifest",
"/*.css",
"/*.js"
]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**",
"/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
]
}
}
]
}
注意:我已尝试从服务工作者中删除所有 css 文件和 ttf、woff 和 woff2 资产。然而它仍然带着更新回来。
非常感谢任何帮助。谢谢。
您是否尝试过查看 v10 specific documentation 并检查以确保它按照您上面的描述正常工作?
看起来无论有没有更新,承诺总是会解决。尝试将 available
observable 与 checkForUpdate()
?
另外,尝试从 ngsw-config.json
中提取您的清单文件,看看是否也有帮助。我以前在该文件中看到过哈希不匹配。
在你的 config.url 之后 ngsw/state
的输出是什么?