Skip to content

Commit

Permalink
feat(service-worker): fix #20970 add option to config when to registe…
Browse files Browse the repository at this point in the history
…r sw
  • Loading branch information
JiaLiPassion committed Jan 30, 2018
1 parent 5bd93b1 commit 020f78e
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
25 changes: 25 additions & 0 deletions aio/content/guide/service-worker-getting-started.md
Expand Up @@ -66,6 +66,31 @@ Add `ServiceWorkerModule` to the `@NgModule` `imports` array. Use the `register(

<code-example path="service-worker-getting-started/src/app/app.module.ts" linenums="false" title="src/app/app.module.ts" region="sw-module"> </code-example>

You can pass some options to the `register()` method.
- enabled: optional parameter, by default is true, if enabled is false, the module will behave like the browser not support service worker, and service worker will not be registered.
- scope: optional parameter, to specify the subset of your content that you want the service worker to control.
- registrationStrategy: optional parameter, specify a strategy that determines when to register the service worker, the available options are:
- registerWhenStable: this is the default behavior, the service worker will register when the application is stable (no microTasks or macroTasks remain).
- registerImmediately: register immediately without waiting the application to become stable.
- registerDelay:timeout : register after the timeout period, `timeout` is the number of milliseconds to delay registration. For example `registerDelay:5000` would register the service worker after 5 seconds. If the number of `timeout` is not given (`registerDelay`), by default, `timeout` will be `0`, but it is not equal to `registerImmediately`, it will still run a `setTimeout(register, 0)` to wait all `microTasks` to finish then perform registration of the service worker.
- A factory to get Observable : you can also specify a factory which returns an Observable, the service worker will be registered the first time that a value is emitted by the Observable.

<code-tabs>
<code-pane title="src/app/app.module.ts">
@NgModule({
imports: [
ServiceWorkerModule.register('/ngsw-worker.js', {enabled: environment.production,
registrationStrategy: environment.getServiceWorkerObservable})
]
})
</code-pane>
<code-pane title="src/app/environments/environments.ts">
export function getServiceWorkerObservable() {
return someService.initData(); // return an Observable, when data is available, we can register service worker.
)};
</code-pane>
</code-tabs>

The file `ngsw-worker.js` is the name of the prebuilt service worker script, which the CLI copies into `dist/` to deploy along with your server.

### Step 4: Create the configuration file, `ngsw-config.json`
Expand Down
31 changes: 28 additions & 3 deletions packages/service-worker/src/module.ts
Expand Up @@ -20,6 +20,7 @@ import {SwUpdate} from './update';
export abstract class RegistrationOptions {
scope?: string;
enabled?: boolean;
registrationStrategy?: (() => Observable<any>)|string;
}

export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT');
Expand Down Expand Up @@ -49,7 +50,30 @@ export function ngswAppInitializer(

// Don't return the Promise, as that will block the application until the SW is registered, and
// cause a crash if the SW registration fails.
whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope}));
if (typeof options.registrationStrategy === 'function') {
const observable = options.registrationStrategy();
const subscription = observable.subscribe(() => {
navigator.serviceWorker.register(script, {scope: options.scope});
subscription.unsubscribe();
});
} else {
const registrationStrategy = typeof options.registrationStrategy === 'string' ?
options.registrationStrategy :
'registerWhenStable';
if (registrationStrategy === 'registerWhenStable') {
whenStable.then(() => navigator.serviceWorker.register(script, {scope: options.scope}));
} else if (registrationStrategy === 'registerImmediately') {
navigator.serviceWorker.register(script, {scope: options.scope});
} else if (registrationStrategy.indexOf('registerDelay') !== -1) {
const split = registrationStrategy.split(':');
const delay = split.length > 1 ? split[1] : 0;
setTimeout(() => navigator.serviceWorker.register(script, {scope: options.scope}), delay);
} else {
// wrong strategy
throw new Error(
`Unknown service worker registration strategy: ${options.registrationStrategy}`);
}
}
};
return initializer;
}
Expand All @@ -73,8 +97,9 @@ export class ServiceWorkerModule {
* If `enabled` is set to `false` in the given options, the module will behave as if service
* workers are not supported by the browser, and the service worker will not be registered.
*/
static register(script: string, opts: {scope?: string; enabled?: boolean;} = {}):
ModuleWithProviders {
static register(script: string, opts: {
scope?: string; enabled?: boolean; registrationStrategy?: (() => Observable<any>) | string;
} = {}): ModuleWithProviders {
return {
ngModule: ServiceWorkerModule,
providers: [
Expand Down
1 change: 1 addition & 0 deletions tools/public_api_guard/service-worker/service-worker.d.ts
Expand Up @@ -3,6 +3,7 @@ export declare class ServiceWorkerModule {
static register(script: string, opts?: {
scope?: string;
enabled?: boolean;
registrationStrategy?: (() => Observable<any>) | string;
}): ModuleWithProviders;
}

Expand Down

0 comments on commit 020f78e

Please sign in to comment.