How to have a service worker with a runtime enabled option?

社会主义新天地 提交于 2021-01-29 14:34:57

问题


I created a lib-pwa library that takes care of the service worker.

Because it's a library I have to feed it the environment from the client application, and not use a local environment definition.

To this end, I use the ng-environmenter dependency in the module of the library.

import { Environmenter } from 'ng-environmenter';

function serviceWorkerFactory(environmenter: Environmenter): SwRegistrationOptions {
  const isProduction: boolean = environmenter.getGlobalEnvironment().environment.production;
  return ({
    enabled: isProduction
  });
};

@NgModule({
  imports: [
    ServiceWorkerModule.register('ngsw-worker.js'),
  ],
  providers: [
    {
      provide: SwRegistrationOptions,
      useFactory: serviceWorkerFactory,
    }
  ]
})
export class LibPwaModule { }

But I cannot see the above logger when using the library in my client application.

Also, another logger tells me the service worker of this library is enabled:

public checkForAppUpdate(): void {
  console.log('PWA - In checkForAppUpdate');
  if (this.swUpdate.isEnabled) {
    console.log('PWA - Update is enabled');
    this.pwaCheckForUpdateSubscription = this.swUpdate.available
      .subscribe(() => {
        console.log('PWA - Offering a new version');
        const appNewVersion: string = this.translateService.instant('app.pwa.new_version_available');
        if (confirm(appNewVersion)) {
          this.screenDeviceService.reloadPage();
        }
      });
  }
}

So it looks like the service worker SwRegistrationOptions options are being ignored.

It's too bad, for I'd like to set its enabled option at runtime.

For information, my client application has the following module:

import { NgModule } from '@angular/core';
import { environment } from '@env/environment';
import { EnvironmenterModule, Environment } from 'ng-environmenter';

export const globalEnvironment = {
  environment: environment,
};

export const environmenter: Environment = {
  application: {},
  global: globalEnvironment
};

@NgModule({
  imports: [
    EnvironmenterModule.forRoot(environmenter),
  ],
  exports: [
    EnvironmenterModule
  ]
})
export class EnvironmentModule { }

UPDATE: My provider was missing the dependency:

deps: [Environmenter],

It turned out I also could not use the multi: true property on the SwRegistrationOptions provider alongside other providers in the same module. Doing so would give the error: Cannot mix multi providers and regular providers

So I had to register the service worker in its own module:

function serviceWorkerFactory(environmenter: Environmenter): SwRegistrationOptions {
  const isProduction: boolean = environmenter.getGlobalEnvironment().environment.production;
  return ({
    enabled: isProduction
  });
};

@NgModule({
  imports: [
    ServiceWorkerModule.register('ngsw-worker.js'),
    EnvironmenterModule
  ],
  providers: [
    {
      provide: SwRegistrationOptions,
      useFactory: serviceWorkerFactory,
      deps: [Environmenter]
    }
  ]
})
export class SWModule { }

来源:https://stackoverflow.com/questions/61634049/how-to-have-a-service-worker-with-a-runtime-enabled-option

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!