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

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.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 26
  • Comments: 26 (5 by maintainers)

Commits related to this issue

Most upvoted comments

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.

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

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/",
...

@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

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

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

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

@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 })

@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 …

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

@gkalpak Will the fix be available for Angular 6?