Angular-cli: ServiceWorker register generated by cli with base-href don't works

Created on 16 Nov 2017  路  26Comments  路  Source: angular/angular-cli

Bug Report or Feature Request (mark with an x)

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

Versions.

Angular CLI: 1.6.0-beta.0
Node: 8.9.0
OS: win32 x64
Angular: 5.0.1
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router, service-worker

@angular/cli: 1.6.0-beta.0
@angular-devkit/build-optimizer: 0.0.33
@angular-devkit/core: 0.0.20
@angular-devkit/schematics: 0.0.35
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.0-beta.0
@schematics/angular: 0.1.3
typescript: 2.4.2
webpack: 3.8.1

Repro steps.

ng new project --service-worker
cd project
ng build --prod --base-href=/project/

then

Publish the dist folder to a web server with a base url /project/
Ex: http://localhost/project/

The log given by the failure.

Failed to fetch ngsw-worker.js at chrome devtools

Desired functionality.

Fetch ngsw-worker.js at chrome devtools and service-worker works!

Mention any other details that might be useful.

At line 16 of app.module.ts generated by cli:

    environment.production ? ServiceWorkerModule.register('/ngsw-worker.js') : []

the register is starting with / which make the fetch start from http://localhost/

If is changed to ./ it will works, but i don't test if the first request to a sub-component can confuse this solution, because the first access would be http://localhost/project/somecomponent/, and the register can try to get from http://localhost/project/somecomponent/ngsw-worker.js

My guess is that ServiceWorkerModule.register could include the base-path by default, then it could solve this problem definitely.

devkibuild-angular high broken bufix

Most helpful comment

Currently, when we add the service-worker(e.g. ng new myapp --service-worker or yarn add @angular/service-worker), angular-cli(1.7.3) or someone adds the code below in app.modules.ts:

ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })

But if we build the app with --base-href /some/other/base/,
getting /ngsw-worker.js fails because ngsw-worker.js exists as /some/other/base/ngsw-worker.js,
not in /.
So, angular-cli (or someone) SHOULD generate the code like below:

ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production })

The path of ngsw-worker.js SHOULD BE RELATIVE.
cf: https://github.com/NastyaSmirnova/PWCat/commit/8f7e5f2410e687794ca75b04f46b66663b3a56e5

According to the PWCat (and my trial), this change works well.

All 26 comments

@alxhub Could you investigate/answer this? Seems like using --base-href breaks SW.

@alxhub We need your help over here!

hello @jvitor83 can you help out,

I have the same problem, I use angular-cli 1.6.7
steps :
ng new project --service-worker
cd project
ng serve --prod

failed to load service worker to register :4200/ngsw-worker.js:-Infinity

thank you

service-worker-cli-failed

--

@hansl - I am also facing the same issue. Any release plan for this?

Same problem with @angular/cli: 1.7.0

I'm trying to publish a PWA using github pages and always got 404 when trying to get the service-worker.

I'm using to publish it a command to automate the process- "deploy-gh-pages": "ng build --prod --base-href 'https://bikecoders.github.io/SoccerTournamentManager/' && ngh"

I fix the problem by hand.... Just open the file main.HASH.bundle.js, search for ngsw-worker.js and add your base

@zmazouzi service worker don't work with ng serve at the moment (even if you pass --prod). see the feature requests: #9631 #9869. you have to run your own server, like http-server to test the service worker - if you did not figure this out since ...

Currently, when we add the service-worker(e.g. ng new myapp --service-worker or yarn add @angular/service-worker), angular-cli(1.7.3) or someone adds the code below in app.modules.ts:

ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })

But if we build the app with --base-href /some/other/base/,
getting /ngsw-worker.js fails because ngsw-worker.js exists as /some/other/base/ngsw-worker.js,
not in /.
So, angular-cli (or someone) SHOULD generate the code like below:

ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production })

The path of ngsw-worker.js SHOULD BE RELATIVE.
cf: https://github.com/NastyaSmirnova/PWCat/commit/8f7e5f2410e687794ca75b04f46b66663b3a56e5

According to the PWCat (and my trial), this change works well.

@u-ryo did you try the scenario where the user never know about your app, then he go to it from a link where it is inside a deeper route like: 'http://localhost/basehref/somecomponent/anothercomponent/' ?
I think the path to the ngsw-worker.js in this scenario will be something like:
http://localhost/basehref/somecomponent/anothercomponent/ngsw-worker.js
and it will not found.

I not have tested, but it is my guess.

@jvitor83 No, I didn't try.
Basically(=by default) ngsw-worker.js is located at the application root, not the site root.
You can customize to relocate ngsw-worker.js, but then you need also to customize the location in app.module.ts.
In the case above, ServiceWorkerModule.register('./somecomponent/anothercomponent/ngsw-worker.js',...)
I don't know how to locate ngsw-worker.js under ./somecomponent/anothercomponent by default.

As mentioned by @u-ryo in https://github.com/angular/angular-cli/issues/8515#issuecomment-374103272, the path should be relative.
(Similar fix for requesting ngsw.json: angular/angular@f582620)

@gkalpak Will the fix be available for Angular 6?

Don鈥檛 see fix on 6 yet. Still has to use workaround ./

ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production })

@Ploppy3, the issue is not in Angular, it is in the boilerplate that the cli generates.
Until this is fixed, it is trivial to fix in your app by replacing /ngsw-worker.js with ngsw-worker.js:

-ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production })
+ServiceWorkerModule.register('.ngsw-worker.js', { enabled: environment.production })

@xmlking ./ngsw-worker.js is not working for me. Can you share your project configs?

ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production })
Work's fine for me.
Thx @gkalpak !

ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production })
Work's fine for me.
Thx @gkalpak !

Hi, It worked for me but It doesn't work in offline mode what shall I do? thanks

ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production })
Work's fine for me.
Thx @gkalpak !

Hi, It worked for me but It doesn't work in offline mode what shall I do? thanks
I have the same problem, i get HTTP error 504 when trying to access offline in Chrome (Desktop).
It works when I try Firefox, did you solve it?

Hey ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production } works fine for me too. But it doesn't work well.
I have registered my service worker and my files were added correctly
image
I have a base path /donde-viajar/mundo/static/. So my service worker was left:
image
This cause that my site does not recognized my page as a Client:
image
But if I open some file added into the service worker in a new tab, I get this:
image
image
So, I can't view my page in offline mode and worse than that, when I reload my page, all files added in the cache, are getting from the server, instead of the service worker.
image

It is not clear to me (neither from the screenshots, nor from the description) what the problem is.
If the problem persists even when using the latest versions, please post a minimal reproduction (e.g. a standalone repo) that we can use to investigate.

@gkalpak basically the service worker is registered, but it don't recognize my page, or mi index, as a cacheable. My url, that point to my index, is http://localhost:9290/donde-viajar/mundo/static?landscapes_tags=beach&distribution_type=family&experiences_tags=art,night_life&date_range_days_amount=30&date_range_month_from=8&date_range_month_to=9&locale=es-AR.
image
I have registered my service worker on:
image
When I reload the page, the index is getting from the server, instead of the service worker:
image
I'm not sure, if it is because i'm using routing or a base path, diferent than localhost:9290/ (in this case). I guess, because of this, none file added to the service worker, are getted from cache, instead of server.

As I said before, I can't be of much help without a reproduction.

@u-ryo I spent some hours trying to figure out the problem. And you solutions worked with different base href then "/" in that case we have to make ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production }) relative. Thank you very much you are the man!

A tiny-bit unrelated but if anyone happens to find this issue when facing similar problems, here's my journey:
I too have a different base
And I do have my ServiceWorkerModule.register('./ngsw-worker.js', { enabled: environment.production }), as the first import and with the ./ before the filename.
It still wasn't enough to even load the ngsw-worker.js file (It would've been in the logs of the http-server)

And it turned out (Thanks to this question) that Service Worker registration is broken as of angular-cli 7.3.8 and you have manually register in main.ts

platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .then(() => {
        if ('serviceWorker' in navigator && environment.production) {
            navigator.serviceWorker.register('./ngsw-worker.js');
        }
    })
    .catch(console.error);

Also don't forget to modify the scope and start_url in the manifest.webmanifest file
And don't forget the last forward slash. I got this message from lighthouse: start_url ("http://localhost:8080/foo") is not in the service worker's scope ("http://localhost:8080/foo/").

By the way is this a bug? I feel like it should ignore the last forward slash.

This is correct

...
    "scope": "/",
    "start_url": "/foo/",
...

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings