5

I have an angular 8 application and very often after deployment I get complains from end users that they are unable to see the new features. Do I need to incorporate cache busting. After a bit of googling i saw the following command

ng build --output-hashing=all

My question here is does ng build --prod using the angular 8 cli take into consideration cache busting or do I need to add the following command in my deployment step. I would also like to know how do i test it

My angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "quickapp": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "css"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "aot": false,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css",
              "src/app/assets/styles/components/buttons.css",
              "src/app/assets/styles/components/forms.css",
              "src/app/assets/styles/components/inputs.css",
              "./node_modules/bootstrap/dist/css/bootstrap.min.css",
              "./node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css"
            ],
            "scripts": [
              "./node_modules/jquery/dist/jquery.min.js",
              "./node_modules/bootstrap/dist/js/bootstrap.js",
              "./node_modules/bootstrap-toggle/js/bootstrap-toggle.js",
              "./node_modules/bootstrap-select/dist/js/bootstrap-select.js",
              "./node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js",
              "./node_modules/moment/moment.js",
              "./src/app/assets/scripts/drive-js.js",
              "./src/app/assets/scripts/external-js.js"
            ]
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "400kb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "quickapp:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "quickapp:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "quickapp:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "tsconfig.app.json",
              "tsconfig.spec.json",
              "e2e/tsconfig.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "quickapp:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "quickapp:serve:production"
            }
          }
        }
      }
    }},
  "defaultProject": "quickapp"
}
Tom
  • 5,859
  • 24
  • 87
  • 182

1 Answers1

2

As you can see in angular.json output hashing is enabled by default. The problem might be that your user is caching index.html file and thus he is not aware of the new chunks. This might be also a problem with cached static files that are not "hashed" by angular. See https://stackoverflow.com/Questions/728616/disable-cache-for-some-images

    "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all", <---- enabled by default
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            }
karoluS
  • 2,066
  • 1
  • 16
  • 31
  • I have updated the post with my angular.json. Unfortunately I dont see any of the settings under the production section. Is that a problem. Do I need to add what you have shared. I had recently upgraded the Angular 5 project to angular 8. I had picked up the angular 8 angular json that gets generated by default when you create a new project. It didnt have these switches – Tom Sep 18 '19 at 10:14
  • This is the default angular.json from angular 8 cli: https://pastebin.com/hxudJux9. You can easily see if the hashing is enabled. After you run ng build --prod you shall see in dist folder files with names like this `runtime-es2015.d61f42a1e4be5689ac82.js`. If the random number changes then you have hasing enabled. – karoluS Sep 18 '19 at 10:19
  • I just ran ng build --prod and without those entries in the json it generated hashing. So is those entries needed ? – Tom Sep 18 '19 at 10:53
  • I can see in you angular.json that you have those entries. Starting at line 50. – karoluS Sep 18 '19 at 10:57
  • When you say the problem might be that your user is caching index.html file does that mean bookmarking the site – Tom Sep 18 '19 at 13:08
  • This is how my httpHeader looks like const header = new HttpHeaders({ 'Content-Type': 'application/json' }); Do you think i need to add additional headers like header ("Pragma-directive: no-cache"); header ("Cache-directive: no-cache"); header ("Cache-control: no-cache"); header ("Pragma: no-cache"); header ("Expires: 0"); – Tom Sep 18 '19 at 13:32
  • Do you think i need to do something liek this https://stackoverflow.com/questions/53232382/how-to-disable-caching-with-httpclient-get-in-angular-6 – Tom Sep 18 '19 at 14:21