angular-cli icon indicating copy to clipboard operation
angular-cli copied to clipboard

[BUG][PWA] Url error in the "ngsw.json" file with a "baseHref" pointing to a file (eg: "/index.html")

Open sitexw opened this issue 7 years ago • 3 comments

Bug Report or Feature Request

- [X] bug report -> please search issues before submitting
- [ ] feature request

From here: https://github.com/angular/angular/issues/26917

Command

- [X] build

Versions

Angular CLI: 7.0.4
Node: 10.8.0 (npm: 6.3.0)
OS: win32 x64
Angular: 7.0.2
... animations, cdk, common, compiler, compiler-cli, core, forms
... http, language-service, material, platform-browser
... platform-browser-dynamic, router, service-worker

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.10.4
@angular-devkit/build-angular     0.10.4
@angular-devkit/build-optimizer   0.10.4
@angular-devkit/build-webpack     0.10.4
@angular-devkit/core              7.0.4
@angular-devkit/schematics        7.0.4
@angular/cli                      7.0.4
@angular/pwa                      0.10.4
@ngtools/webpack                  7.0.4
@schematics/angular               7.0.4
@schematics/update                0.10.4
rxjs                              6.3.3
typescript                        3.1.6
webpack                           4.19.1

Current behavior

I have a problem with the file ngsw.json (dist/xxx/ngsw.json), when I build my application. Here is the configuration of my file angular.json:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "xxxxxx-xxxxxx-web": {
      ...
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "baseHref": "/index.html",   <-- baseHref with path to a file
            ...
          },
          "configurations": {
            "develop": {
              ...
              "baseHref": "/dev-web-xxxxxx-xxxxxx/index.html",   <-- baseHref with path to a file
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.develop.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": true,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "serviceWorker": true
            }
            ...

As you can see, my baseHref points to a file (index.html). And when I compile, here is the result of the file ngsw.json:

{
  "configVersion": 1,
  "index": "/dev-web-xxxxxx-xxxxxx/index.html/index.html",
  "assetGroups": [                 ^^^^^^^^^^
    {
      "name": "app",
      "installMode": "prefetch",
      "updateMode": "prefetch",
      "urls": [                 vvvvvvvvvv
        "/dev-web-xxxxxx-xxxxxx/index.html/4.459d2c031076fa54578c.js",
        "/dev-web-xxxxxx-xxxxxx/index.html/5.b0a92526f07730e41004.js",
        "/dev-web-xxxxxx-xxxxxx/index.html/index.html",
        "/dev-web-xxxxxx-xxxxxx/index.html/main.284d15247a9766d625e1.js",
        "/dev-web-xxxxxx-xxxxxx/index.html/polyfills.f8bea440aac573c30541.js",
        "/dev-web-xxxxxx-xxxxxx/index.html/runtime.e04cbf91ceee4f9b3494.js",
        "/dev-web-xxxxxx-xxxxxx/index.html/styles.380a38f67b77a997829f.css"
      ],                        ^^^^^^^^^^
      "patterns": []
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "urls": [                 vvvvvvvvvv
        "/dev-web-xxxxxx-xxxxxx/index.html/assets/icons/icon-128x128.png",
        "/dev-web-xxxxxx-xxxxxx/index.html/assets/icons/icon-144x144.png",
        ...                     ^^^^^^^^^^

As you can see, it generates all the urls of the file with the .../index.html/..., as if it were a folder. As this file is used for the cache of the application, the cache does not work since it is not the right url...

Expected behavior

I think the file should have looked like this:

{
  "configVersion": 1,
  "index": "/dev-web-xxxxxx-xxxxxx/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "updateMode": "prefetch",
      "urls": [
        "/dev-web-xxxxxx-xxxxxx/4.459d2c031076fa54578c.js",
        "/dev-web-xxxxxx-xxxxxx/5.b0a92526f07730e41004.js",
        "/dev-web-xxxxxx-xxxxxx/index.html",
        "/dev-web-xxxxxx-xxxxxx/main.284d15247a9766d625e1.js",
        "/dev-web-xxxxxx-xxxxxx/polyfills.f8bea440aac573c30541.js",
        "/dev-web-xxxxxx-xxxxxx/runtime.e04cbf91ceee4f9b3494.js",
        "/dev-web-xxxxxx-xxxxxx/styles.380a38f67b77a997829f.css"
      ],
      "patterns": []
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "urls": [
        "/dev-web-xxxxxx-xxxxxx/assets/icons/icon-128x128.png",
        "/dev-web-xxxxxx-xxxxxx/assets/icons/icon-144x144.png",
        ...

Minimal reproduction of the problem with instructions

You just have to create an application (which uses PWA) and have a baseHref that points to a file (eg: index.html). And when you compile your application, the url generated in the ngsw.json file will be wrong.

What is the motivation / use case for changing the behavior?

I think it would just take into account when the "baseHref" to deal with a file, take the root of the file (and not take the file for a folder).

For information, I use a baseHref to a file, because I use the system of route of Angular with the hash and that the url https://storage.googleapis.com/dev-web-xxxxxx-xxxxxx/ does not point towards my file index.html. As the project is hosted on a Google Cloud Storage, when we update the application (CTRL+F5, ...) with a url of this type ...-xxxxxx/#/user/login, I end up with a 404 error (because the url in ...-xxxxxx/ does not point to the file index.html). To solve this problem, I force Angular to keep the index.html in the URL (eg: ...-xxxxxx/index.html#/user/login), through baseHref with the index.html in it.

For now, I make the corrections of the url in the file ngsw.json manually, so that the cache of the application works...

sitexw avatar Nov 02 '18 11:11 sitexw

Hi, thanks for reporting this.

Can you explain why your Google Cloud Storage bucket is not configured to point to the index.html?

Most likely setting the baseHref to a file, will have other repercussions when using lazy loading, css assets if absolute paths are used etc.

alan-agius4 avatar Dec 05 '18 09:12 alan-agius4

@alan-agius4, what other repercussions do you have in mind? Using a file as baseHref is valid. IMO, cli should suport that and treat it the same way as it will be treated in the browser (i.e. ignore the file part if it wants to combine it with a relative path).

gkalpak avatar Dec 05 '18 12:12 gkalpak

@gkalpak, I totally agree!

My point was that when baseHref is a file it is not being set properly not only in service worker, but applies to a lot of other user cases. Such as lazy loading, absolute css resources etc...

So setting the baseHref to a file at the moment will break not only the service worker but other functionality (depending on what functionality you are using).

And I agree that it should be addressed 😀

alan-agius4 avatar Dec 06 '18 15:12 alan-agius4