Skip to content
Permalink
Browse files

feat(service-worker): allow configuring when the SW is registered (#2…

…1842)

Fixes #20970

PR Close #21842
  • Loading branch information...
JiaLiPassion authored and AndrewKushnir committed Jan 28, 2018
1 parent aa53d6c commit 4cfba58072bd288dff58714db44e9b7edef4bc92
@@ -218,3 +218,15 @@ If the field is omitted, it defaults to:
'!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
]
```

## `register options`

<code-example path="service-worker-getting-started/src/app/app.module.ts" linenums="false" header="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.
@@ -1,7 +1,7 @@
# Getting started with service workers


This document explains how to enable Angular service worker support in projects that you created with the [Angular CLI](cli). It then uses a simple example to show you a service worker in action, demonstrating loading and basic caching.
This document explains how to enable Angular service worker support in projects that you created with the [Angular CLI](cli). It then uses a simple example to show you a service worker in action, demonstrating loading and basic caching.

#### Prerequisites

@@ -10,26 +10,26 @@ A basic understanding of the information in [Introduction to Angular service wor

## Adding a service worker to your project

To set up the Angular service worker in your project, use the CLI command `ng add @angular/pwa`. It takes care of configuring your app to use service workers by adding the `service-worker` package along
To set up the Angular service worker in your project, use the CLI command `ng add @angular/pwa`. It takes care of configuring your app to use service workers by adding the `service-worker` package along
with setting up the necessary support files.

```sh
ng add @angular/pwa --project *project-name*
ng add @angular/pwa --project *project-name*
```

The above command completes the following actions:

1. Adds the `@angular/service-worker` package to your project.
1. Adds the `@angular/service-worker` package to your project.
2. Enables service worker build support in the CLI.
3. Imports and registers the service worker in the app module.
4. Updates the `index.html` file:
* Includes a link to add the `manifest.json` file.
* Adds meta tags for `theme-color`.
5. Installs icon files to support the installed Progressive Web App (PWA).
6. Creates the service worker configuration file called [`ngsw-config.json`](/guide/service-worker-config), which specifies the caching behaviors and other settings.
6. Creates the service worker configuration file called [`ngsw-config.json`](/guide/service-worker-config), which specifies the caching behaviors and other settings.


Now, build the project:
Now, build the project:

```sh
ng build --prod
@@ -40,8 +40,8 @@ The CLI project is now set up to use the Angular service worker.

## Service worker in action: a tour

This section demonstrates a service worker in action,
using an example application.
This section demonstrates a service worker in action,
using an example application.

### Serving with `http-server`

@@ -61,7 +61,7 @@ With the server running, you can point your browser at http://localhost:8080/. Y

### Simulating a network issue

To simulate a network issue, disable network interaction for your application. In Chrome:
To simulate a network issue, disable network interaction for your application. In Chrome:

1. Select **Tools** > **Developer Tools** (from the Chrome menu located at the top right corner).
2. Go to the **Network tab**.
@@ -73,9 +73,9 @@ To simulate a network issue, disable network interaction for your application. I

Now the app has no access to network interaction.

For applications that do not use the Angular service worker, refreshing now would display Chrome's Internet disconnected page that says "There is no Internet connection".
For applications that do not use the Angular service worker, refreshing now would display Chrome's Internet disconnected page that says "There is no Internet connection".

With the addition of an Angular service worker, the application behavior changes. On a refresh, the page loads normally.
With the addition of an Angular service worker, the application behavior changes. On a refresh, the page loads normally.

If you look at the Network tab, you can verify that the service worker is active.

@@ -107,12 +107,12 @@ Pay attention to two key points:

### Making changes to your application

Now that you've seen how service workers cache your application, the
next step is understanding how updates work.
Now that you've seen how service workers cache your application, the
next step is understanding how updates work.

1. If you're testing in an incognito window, open a second blank tab. This will keep the incognito and the cache state alive during your test.

2. Close the application tab, but not the window. This should also close the Developer Tools.
2. Close the application tab, but not the window. This should also close the Developer Tools.

3. Shut down `http-server`.

@@ -156,4 +156,4 @@ The service worker installed the updated version of your app *in the background*
## More on Angular service workers

You may also be interested in the following:
* [Communicating with service workers](guide/service-worker-communications).
* [Communicating with service workers](guide/service-worker-communications).
@@ -8,6 +8,7 @@

import {isPlatformBrowser} from '@angular/common';
import {APP_INITIALIZER, ApplicationRef, InjectionToken, Injector, ModuleWithProviders, NgModule, PLATFORM_ID} from '@angular/core';
import {Observable} from 'rxjs';
import {filter, take} from 'rxjs/operators';

import {NgswCommChannel} from './low_level';
@@ -41,6 +42,8 @@ export abstract class SwRegistrationOptions {
* [ServiceWorkerContainer#register()](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register).
*/
scope?: string;

registrationStrategy?: (() => Observable<any>)|string;
}

export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT');
@@ -68,7 +71,33 @@ 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 delayStr = split.length > 1 ? split[1] : undefined;
const delay = Number(delayStr);
setTimeout(
() => navigator.serviceWorker.register(script, {scope: options.scope}),
typeof delay === 'number' ? delay : 0);
} else {
// wrong strategy
throw new Error(
`Unknown service worker registration strategy: ${options.registrationStrategy}`);
}
}
};
return initializer;
}
@@ -21,6 +21,7 @@ export declare class SwPush {

export declare abstract class SwRegistrationOptions {
enabled?: boolean;
registrationStrategy?: (() => Observable<any>) | string;
scope?: string;
}

0 comments on commit 4cfba58

Please sign in to comment.
You can’t perform that action at this time.