我有一个用Angular编写的web应用程序,用Docker进行容器化。我以前用这些很好的解决方案解决了运行时环境变量的问题(用于开发/生产环境):How to pass environment variables to a frontend web application?
但是!当您编写Angular PWA时,对文件的任何构建后更改,甚至是index.html,都会破坏您的PWA:服务工作者将无法验证您的文件,因为与ngsw.json相比,散列发生了变化。
我想不出用Angular PWA和Docker保持“一次构建,到处部署”模式的好方法。
有什么想法吗?
谢谢你的帮助。
发布于 2021-07-02 04:53:46
在运行时容器修改环境变量后,我的main*.js文件在ngsw.json中出现了这个问题。我想出的解决方案是从Angular的ngsw-config.json中删除有问题的文件,并且不依赖它。
接下来,创建一个单独的sw脚本(我的脚本是sw-handle-main.js),在sw-master脚本文件中,调用sw-handle-main上的importScripts,并调用Angular创建的ngsw-worker.js上的importScripts。确保在ServiceWorkerModule.register调用中注册了这个主js文件,并首先导入您的自定义文件,如下所示:
sw-master.js
importScripts('./sw-handle-main.js');
importScripts('./ngsw-worker.js');在您的脚本中,您需要创建一个调用getElementsByTagName(‘app.component.ts’)的方法,并检查每个src属性。如果src url包含"main“(在我的示例中),则将该src url推送到数组中。然后调用postMessage方法将此数据传递给sw-handle-main。在sw-handle-main.js中,侦听"message“事件,并将urls传递给cache.add()调用。您还需要在fetch事件上添加一个事件侦听器并调用event.respondWith()。不要等到在任何promise中调用event.respondWith(),否则ngsw-worker将吞噬它,并且您的文件永远不会为它注册获取侦听器。通过传递一些同步条件来同步调用它。我的sw-handle-main是这样的:
self.addEventListener('message', event => {
event.waitUntil(initCacheAction(event.data.urls))
});
self.addEventListener('fetch', event => {
const req = event.request
const url = req.url
if(url.indexOf('main') > -1 && url.endsWith('.js')){
event.respondWith(matchJSFile(req))
}
});matchJSFile(请求)是一个承诺。将一个传递给respondWith()是可以的。就像我之前说过的那样,不要等到在异步方法中调用respondWith。
**另一个技巧是基本上从Angular软件中窃取appVersion,如下所示:
function getAppVersion() {
const cachePrefix = 'ngsw:/:'
const cacheSuffix = 'app:cache'
return caches.keys().then( cacheKeys => {
//get any ngsw caches that holds appShell
const appCache = cacheKeys.filter( item => {
return item.indexOf(cacheSuffix) > -1
})
const len = appCache.length
//use the last 1 inserted
const appCacheName = appCache[len - 1]
if(appCacheName){
//lets us know sw app version
return appCacheName.
replace(cachePrefix, '').
replace(cacheSuffix, '')
}
return null
})}
cachePrefix和cacheSuffix是Angular为包含应用程序外壳的缓存对象指定的固定名称。它们之间的长随机字符串是您的appVersion。您还可以在/ngsw/状态下进行验证。有了这个,你可以在你的自定义缓存对象中使用这个键,并保持你的自定义缓存的完整性/新近,并删除你创建的与这个键不匹配的旧缓存!如果你想要更多我的实用程序代码,请让我知道,但这对我很有效!我真的希望我解释得足够好,你可以让你的工作!
https://stackoverflow.com/questions/65196608
复制相似问题