首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在不破坏Angular PWA的情况下使用Docker运行时更改的环境变量

如何在不破坏Angular PWA的情况下使用Docker运行时更改的环境变量
EN

Stack Overflow用户
提问于 2020-12-08 17:48:31
回答 1查看 178关注 0票数 1

我有一个用Angular编写的web应用程序,用Docker进行容器化。我以前用这些很好的解决方案解决了运行时环境变量的问题(用于开发/生产环境):How to pass environment variables to a frontend web application?

但是!当您编写Angular PWA时,对文件的任何构建后更改,甚至是index.html,都会破坏您的PWA:服务工作者将无法验证您的文件,因为与ngsw.json相比,散列发生了变化。

我想不出用Angular PWA和Docker保持“一次构建,到处部署”模式的好方法。

有什么想法吗?

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

发布于 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

代码语言:javascript
复制
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是这样的:

代码语言:javascript
复制
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,如下所示:

代码语言:javascript
复制
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/状态下进行验证。有了这个,你可以在你的自定义缓存对象中使用这个键,并保持你的自定义缓存的完整性/新近,并删除你创建的与这个键不匹配的旧缓存!如果你想要更多我的实用程序代码,请让我知道,但这对我很有效!我真的希望我解释得足够好,你可以让你的工作!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65196608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档