【问题标题】:Angular app has to clear cache after new deploymentAngular 应用程序必须在新部署后清除缓存
【发布时间】:2019-08-19 12:40:38
【问题描述】:

我们有一个 Angular 6 应用程序。它在 Nginx 上提供。 SSL 已开启。

当我们部署新代码时,大多数新功能都可以正常工作,但对于某些更改则不行。例如,如果前端开发人员更新并部署服务连接,用户必须打开隐身窗口或清除缓存才能看到新功能。

哪些类型的更改不会自动更新?为什么他们与其他人不同?

避免该问题的常见解决方案是什么?

【问题讨论】:

    标签: javascript angular nginx deployment


    【解决方案1】:

    问题是当一个静态文件被缓存时,它可能会被存储很长一段时间,然后才会过期。如果您对网站进行更新,这可能会令人烦恼,但是,由于文件的缓存版本存储在访问者的浏览器中,他们可能无法看到所做的更改。

    Cache-busting 通过使用唯一的文件版本标识符来告诉浏览器该文件的新版本可用,从而解决了浏览器缓存问题。因此,浏览器不会从缓存中检索旧文件,而是向源服务器请求新文件。

    Angular cli 通过为构建命令提供 --output-hashing 标志来解决此问题。

    查看官方文档:https://angular.io/cli/build

    示例(旧版本)

    ng build --prod --aot --output-hashing=all
    

    下面是你可以传入--output-hashing的选项

    • 无:不执行散列
    • 媒体:仅向通过 [url|file]-loaders 处理的文件添加哈希
    • bundles:只在输出 bundles 中添加哈希
    • 全部:向媒体和捆绑包添加哈希

    更新

    对于较新版本的 Angular(例如 Angular 10),该命令现已更新:

    ng build --prod --aot --outputHashing=all
    

    【讨论】:

    • 它有效。谢谢你的解决方案。你能解释一下什么情况会导致这个问题吗?正如我所提到的,问题不会发生在所有更新中。
    • @zhangjinzhou 更新答案并附上解释,如果对你有帮助请标记为答案
    • 感谢您的解释!
    • 谢谢。如果我使用这个命令,是只影响当前应用还是整个浏览器?
    • 不幸的是,这对我不起作用,最新的 CLI 已经在 angular.json 中为所有环境添加了 outputHashing:all。 :(
    【解决方案2】:

    为我添加:

        ng build --aot --output-hashing=all
    

    只有构建命令是不够的,当你有你的应用程序时 在 CDN 和良好的缓存 nginx 配置之后。

    1- 首先是删除 html 文件的缓存(nginx):

        location ~ \.(html)$ {
            add_header Pragma "no-cache";
            add_header Cache-Control "no-store";
            add_header strict-transport-security "max-age=31536000";
            add_header X-Frame-Options "SAMEORIGIN";
            try_files $uri $uri/ /index.html;
        }
    

    对于静态文件 (js/css ...) 保持缓存工作(网络性能/可用性):

        location ~ \.(css|htc|less|js|js2|js3|js4)$ {
            expires 31536000s;
            add_header Pragma "public";
            add_header Cache-Control "max-age=31536000, public";
            try_files $uri $uri/ /index.html;
        }
    

    2- 出于测试目的,让 dev/prod 构建完全相同。 最终构建开发命令:

        ng build --env=dev --aot=true --output-hashing=all --extract-css=true 
    

    3- 我们需要在每次部署客户端浏览器时从服务器加载所有 javascript 文件,而不是从缓存中加载, 即使部署是次要更新。 就像角度有一些错误: https://github.com/angular/angular-cli/issues/10641 发生在我身上。

    我结束了使用 bash 的强大功能,这是我用于杀死缓存的脚本 在使用 package.json 文件的每个开发(产品/开发)上:

    "scripts": {
     ...
        "deploy_dev": "ng build --env=dev --aot=true --output-hashing=all --extract-css=true && npm run add_date",
        "deploy_prd": "ng build --prod && npm run add_date",
        "add_date": "npm run add_date_js && npm run add_date_css && npm run rm_bak_files",
        "add_date_js": "for i in dist/*; do if [ -f $i ]; then LC_ALL=C sed -i.bak 's:js\":js?'$(date +%H%M%m%d%y)'\":g' $i; fi done",
        "add_date_css": "sed -i.bak 's:css\":css?'$(date +%H%M%m%d%y)'\":g' dist/index.html",
        "rm_bak_files": "find dist -name '*.bak' -exec rm -Rf {} \\;"
    },
    

    命令说明:
    add_date_js:用“js?{date+%H%M%m%d%y}”查找并替换所有文件“js”
    add_date_css:在 dist/index.html "css" 中查找并替换为 "css?{date+%H%M%m%d%y}"
    rm_bak_files:删除所有.bak文件(网络性能)

    这些 sed 命令适用于 GNU/BSD/Mac。

    链接:
    Angular - Prod Build not generating unique hashes
    sed in-place flag that works both on Mac (BSD) and Linux
    RE error: illegal byte sequence on Mac OS X
    Inline if shell script
    How to loop over files in directory and change path and add suffix to filename
    Is it possible to build separate CSS file with angular-cli?

    【讨论】:

    • Isaac,我没有 Win,但你可以轻松地制作一个 docker 来做这件事
    • @AlejoJM,我知道.. 这个答案很老了。但是重命名 javascript 文件的脚本不起作用。不重命名不文件!默默执行
    • hello @k.vincent 你需要检查你的 dist 目录结构,这些命令假设你的 dist 文件夹有 app dist/index.html,如果你有你的 dist/{appName} 命令将会失败
    • 是的,我确实有不同的结构,例如:dist/{appName}/{lang}。这是否意味着它仅适用于以下结构:dist/
    【解决方案3】:

    虽然accepted answer above 可以工作,但应该在angular.json中进行此调整,在configurations => <my-env-name> => outputHashing => 设置为all (用于生产环境)。

    简化示例:

    {
      "projects": {
        "<my-project>": {
          "architect": {
            "build": {
              "configurations": {
                "<my-env-name>": {
                  "outputHashing": "all"
                }
              }
            }
          }
        }
      }
    }
    
    

    正如上述帖子中所述,此配置的可用选项:

    • :不执行散列
    • 媒体:仅向通过 [url|file]-loaders 处理的文件添加哈希
    • bundles:仅将哈希添加到输出包中
    • 全部:向媒体和捆绑包添加哈希

    【讨论】:

    猜你喜欢
    • 2020-08-31
    • 2021-05-30
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-05-31
    • 2020-10-26
    • 2014-06-06
    • 1970-01-01
    相关资源
    最近更新 更多