3

Update 1/2/22: I downgraded to version 11.1.2 (same version as another app of mine which didn't have this issue) and the issue no longer appears. While this allows me to move forward, I more or less circumvented the issue than resolved it. I'll leave this open and hopefully a true fix can be discovered.

Original Post:

I need my Angular 13.0.0 app to run offline (no Internet) and in a war with embedded tomcat. The initial page is a login page and the HTML and Javascript (compiled TS) seem to work fine as logging in reaches the back end successfully and the home page loads. Upon commenting out my styles.scss file and running online, I'm seeing the exact issue. In addition, running offline via Angular CLI does not produce this issue.

I can literally leave the executable war running and disable my wifi to go from having CSS to not having it. The opposite is also true. Based on that, the issue appears to be completely in the front end.

I've done this with other applications but older versions (11.1.2 and 10.0.0-rc.6 and not using embedded containers) this issue doesn't occur. I've reviewed the angular.json files from those applications and I don't see any glaring differences. Did something change in the newer versions of Angular? Otherwise, there’s something I may be missing due to the container being embedded.

The entire app is missing CSS but to keep it simple here is how my login page looks:

  • Offline: enter image description here

  • Online:

enter image description here

Here is my angular.json:

  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "cli": {
    "analytics": false
  },
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "client": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "../src/main/resources/static",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "development": {
              "sourceMap": true,
              "optimization": false
            },
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "20mb",
                  "maximumError": "25mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "20mb",
                  "maximumError": "25mb"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "client:build:development"
          },
          "configurations": {
            "production": {
              "browserTarget": "client:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "client:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": [
              "src/styles.scss"
            ],
            "scripts": [],
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    },
    "client-e2e": {
      "root": "e2e/",
      "projectType": "application",
      "prefix": "",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "client:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "client:serve:production"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "e2e/tsconfig.e2e.json",
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    }
  },
  "defaultProject": "client"
}

And my client build.gradle file:

plugins {
  id "com.github.node-gradle.node" version "3.1.1"
}

node {
  version = '17.0.1'
  npmVersion = '8.1.0'
  download = true
  workDir = file("${project.buildDir}/node")
  nodeModulesDir = file("${project.projectDir}")
}

task buildClient(type: NpmTask) {
  group = 'build'
  description = 'Compile client side assets for production'
  args = ['run', 'build:prod']
}
buildClient.dependsOn(npm_install)

And finally, my main build.gradle file (there are only two):

buildscript {
    ext {
        springBootVersion = '2.4.3'
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}


plugins {
    id 'org.springframework.boot' version "${springBootVersion}"
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

apply plugin: 'war'

group = 'com.group.'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

task deleteStaticFolder(type: Delete) {
    def dirName = "src/main/resources/static"
    file( dirName ).list().each{
        f ->
            delete "${dirName}/${f}"
    }
}

processResources.dependsOn('client:buildClient')
println 'Using build.gradle'

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-rest'
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.3.9.RELEASE'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: '2.5.6'
    compileOnly 'org.projectlombok:lombok'
    implementation 'com.microsoft.sqlserver:mssql-jdbc'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    // https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-csv
    implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-csv', version: '2.13.0'
    // https://mvnrepository.com/artifact/com.jcraft/jsch
    implementation group: 'com.jcraft', name: 'jsch', version: '0.1.55'
// https://mvnrepository.com/artifact/com.unboundid/unboundid-ldapsdk
    implementation group: 'com.unboundid', name: 'unboundid-ldapsdk', version: '5.1.4'
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-websocket
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.5.6'
}

test {
    useJUnitPlatform()
}

I've spent way too much time on this and I'm out of ideas. Things I’ve tried:

  • Update 12/28/21 - created a simple CSS class (changing the background color) in styles.scss and referenced it in the login component template. With an Internet connection, the class was applied, without a connection it was not.
  • Different things in the angular.json related to architect/build/configurations/production`
  • Commenting out the RequestFilter class in my spring boot code
  • Cleared browser cache to make sure online/offline comparisons are accurate

Network tab:

  • Offline: enter image description here
  • Online: enter image description here

Console:

  • Offline: enter image description here
  • Online: enter image description here

The missing theme console warning is suspicious but as it appears even when the CSS is working I am not convinced it's related.

Finally, the Roboto font error is also present in the console for my other apps but doesn't impact their CSS so again I don't believe is causing my CSS to be MIA.

Thank you in advance!

Athlon
  • 71
  • 1
  • 5
  • Please see this answer: I will hope help you https://stackoverflow.com/questions/37270835/how-to-host-material-icons-offline – Mahyar8520 Jan 03 '22 at 01:48
  • 1
    To have your angular resources in handy, you can use the `@angular/pwa` or `@angular/service-worker` – Pieterjan Jan 03 '22 at 07:14
  • @Mahyar8520 thanks but my issue is not with the icons, it's with all CSS. – Athlon Jan 10 '22 at 17:48
  • @Pieterjan this sounds promising. I'll take a look, thanks. – Athlon Jan 10 '22 at 17:48
  • @Pieterjan I followed this tutorial on `service-workers`: https://blog.angular-university.io/angular-service-worker/ but the issue remains. When I reach the login page (while offline), the CSS is gone and my browser's `Application/Cache Storage` shows an entry for `ngsw:/:db:control - http://localhost:8444` but there are no cache entries. It seems like there should be some entries there. In `ngsw-config.json`, the assetGroup for app has an installMode of `prefetch` which I believe includes it in the build. Do you have any suggestions? – Athlon Jan 10 '22 at 22:25

0 Answers0