【问题标题】:How to handle Angular 2+ code updates?如何处理 Angular 2+ 代码更新?
【发布时间】:2017-11-22 17:21:11
【问题描述】:

当 Angular 2+ 应用更新时,有没有办法处理?

注意:不是 Angular 更新时,例如从 4.1.0 到 4.1.2(这不是)

当我说“更新”时,我的意思是:

代码更改时并发布到生产环境。

当我发布 Angular 4 内置系统的更新时,客户端的视图开始出现错误,因为 NG 的 javascript 已更改,甚至有其他 javascript 生成的名称。

  • 处理这个问题的正确方法是什么?

  • Angular 在何时更新代码/资源时对浏览器有“一些”官方说法?

或类似的东西。

谢谢。

【问题讨论】:

  • 目前还不清楚到底是什么问题,例如NG 的javascript 发生了变化,甚至还有其他javascript 生成的名称 的含义。如果问题是 JS 脚本被缓存在浏览器端并且没有自动更新,这与 Angular 无关。这是关于特定于服务器端的缓存失效。如果您使用的是 Angular CLI(问题没有说明这一点),可能会有支持它的解决方案。
  • 问题是当一个内置 Angular 的应用程序发布时,客户端访问我们的站点“example.com”并获取该 Angular 视图的当前版本,但是当你修复类似错误的东西时,你重新- 发布更改。但客户必须刷新才能看到这种变化。大多数客户不知道更改何时发布。 Angular 如何自动处理这个问题。
  • 不能。它可以是随机的 JS 脚本,结果是一样的。同样,这是特定于您的服务器端的。不是角的。更新的脚本文件应该有不同的文件名(包含版本或散列),或不同的 url(? 带有版本或散列的查询)。缓存失效在 SO 上讨论了很多次。如果您无法从现有答案中解决问题,请考虑在服务器端重新提出问题并提供准确的详细信息。
  • 我不认为@NinjaCoding 指的是缓存失效,而是通过应用程序通知用户应用程序已更改。
  • 如果没有 Web 套接字连接,或者是否已经在客户端和服务器上内置了用于检查代码更新的逻辑,您无法真正告诉浏览器何时更新。不过一般来说,如果没有 API 更新,我看不出旧代码会因为世界上存在新版本而突然中断。

标签: javascript angular


【解决方案1】:

我认为部署新代码时没有“官方”方式强制客户端重新加载。通常这应该不是问题,因为当客户端调用应用程序时,它会缓存 JS 和 CSS 文件,因此部署不应对客户端当前运行的应用程序版本产生任何影响...

但如果这确实是个问题,您可以通过 HTTP API 提供您的应用程序版本,让您的 Angular 应用程序在每次交互时检查它,并在版本更改时重新加载页面。

version.txt

1.0.1

src/environments/environment.prod.ts

export const environment = {
    production: true,
    version: '1.0.2'
};

src/app/version.service.ts

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {environment} from '../environments/environment';

@Injectable()
export class VersionService {
    constructor(private __httpClient: HttpClient) { }

    checkVersion() {
        this.__httpClient.get('/version.txt').subscribe(data => {
            if (data != environment.version) {
                alert('Code is outdated, website will reload');
                window.reload();
            }
        }
    }
}

为所有组件添加构造函数并检查版本

src/app/app.component.ts

constructor(private __versionService: VersionService) {
    this.__versionService.checkVersion();
}

注意:此代码完全未经测试 :-) 您可能需要修改它...另外,我不确定这是否真的是最好的方法,但我无法在任何地方找到更好的答案要么。

【讨论】:

    【解决方案2】:

    非常感谢@masterfloda!!

    我一直在按照您的方法工作,而且效果很好,我对您的代码进行了一些调整,所以希望您不介意我发布更新的代码以帮助其他面临同样问题的人。

    version.txt

    1.0
    

    我注意到,当数字之间超过一个点 (0.0.0 -> 0.0) 时,比较值会失败。

    我没有使用 src/environments/environment.prod.ts 方法,因为我想要一种方法来更新 src/environments/environment.prod.ts 中的版本值,但不知道如何在生产,所以我将值存储在本地存储中。

    src/app/version.service.ts

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Compiler } from '@angular/core';
    import { GlobalVariablesService } from '../services/global.service';
    
    //https://stackoverflow.com/questions/47440576/how-to-handle-angular-2-code-updates
    @Injectable()
    export class VersionService {
        constructor(private __httpClient: HttpClient,
          private _compiler: Compiler,
          public variablesService: GlobalVariablesService
        ) { }
    
        checkVersion() {
            this.__httpClient.get('https://host.com/version.txt?'+Math.round(Math.random() * 10000),{responseType: 'text'}).subscribe(
              response => {
    
                let text_version  = response;
                let stored_version = this.variablesService.getVersion();
                //alert('text_version: '+text_version);
    
                if(stored_version == undefined){
                  this.variablesService.setVersion(text_version);
                } else if (+text_version != +stored_version) {
                    this.reloadAndStore(text_version);
               }
            },
            error => {
             console.log(<any>error);
              }
            );
          }
    
          reloadAndStore(text_version){
            //alert('Code is outdated, website will reload');
            this._compiler.clearCache();
            this.variablesService.setVersion(text_version);
            location.reload();
    
          }
    
        }
    

    version.txt?'+Math.round(Math.random() * 10000)

    在这里你会看到我使用了一个随机参数,因为如果我没有注意到当 web 应用程序安装在 ios 主屏幕中时,它甚至会捕获那个 version.text 文件。

    ../services/global.service

    ...
          getVersion() {
            if(this.deCodeLocal('storedVersion') === null){
              return undefined;
            } else {
              return this.deCodeLocal('storedVersion');
            }
          }
    
    
    
          setVersion(val) {
            this.enCodeLocal('storedVersion', val);
          }
    ...
    

    src/app/app.component.ts

    constructor(private __versionService: VersionService) {
        this.__versionService.checkVersion();
    }
    

    希望对大家有帮助,非常感谢。

    【讨论】:

      猜你喜欢
      • 2017-11-03
      • 1970-01-01
      • 2017-10-21
      • 2017-04-30
      • 1970-01-01
      • 2018-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多