feat(service-worker): allow configuring when the SW is registered (#21842)
Fixes #20970 PR Close #21842
This commit is contained in:
parent
aa53d6cc6d
commit
4cfba58072
|
@ -218,3 +218,15 @@ If the field is omitted, it defaults to:
|
||||||
'!/**/*__*/**', // Exclude URLs containing `__` in any other segment.
|
'!/**/*__*/**', // 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
|
# 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
|
#### Prerequisites
|
||||||
|
|
||||||
|
@ -10,26 +10,26 @@ A basic understanding of the information in [Introduction to Angular service wor
|
||||||
|
|
||||||
## Adding a service worker to your project
|
## 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.
|
with setting up the necessary support files.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ng add @angular/pwa --project *project-name*
|
ng add @angular/pwa --project *project-name*
|
||||||
```
|
```
|
||||||
|
|
||||||
The above command completes the following actions:
|
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.
|
2. Enables service worker build support in the CLI.
|
||||||
3. Imports and registers the service worker in the app module.
|
3. Imports and registers the service worker in the app module.
|
||||||
4. Updates the `index.html` file:
|
4. Updates the `index.html` file:
|
||||||
* Includes a link to add the `manifest.json` file.
|
* Includes a link to add the `manifest.json` file.
|
||||||
* Adds meta tags for `theme-color`.
|
* Adds meta tags for `theme-color`.
|
||||||
5. Installs icon files to support the installed Progressive Web App (PWA).
|
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
|
```sh
|
||||||
ng build --prod
|
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
|
## Service worker in action: a tour
|
||||||
|
|
||||||
This section demonstrates a service worker in action,
|
This section demonstrates a service worker in action,
|
||||||
using an example application.
|
using an example application.
|
||||||
|
|
||||||
### Serving with `http-server`
|
### 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
|
### 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).
|
1. Select **Tools** > **Developer Tools** (from the Chrome menu located at the top right corner).
|
||||||
2. Go to the **Network tab**.
|
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.
|
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.
|
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
|
### Making changes to your application
|
||||||
|
|
||||||
Now that you've seen how service workers cache your application, the
|
Now that you've seen how service workers cache your application, the
|
||||||
next step is understanding how updates work.
|
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.
|
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`.
|
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
|
## More on Angular service workers
|
||||||
|
|
||||||
You may also be interested in the following:
|
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 {isPlatformBrowser} from '@angular/common';
|
||||||
import {APP_INITIALIZER, ApplicationRef, InjectionToken, Injector, ModuleWithProviders, NgModule, PLATFORM_ID} from '@angular/core';
|
import {APP_INITIALIZER, ApplicationRef, InjectionToken, Injector, ModuleWithProviders, NgModule, PLATFORM_ID} from '@angular/core';
|
||||||
|
import {Observable} from 'rxjs';
|
||||||
import {filter, take} from 'rxjs/operators';
|
import {filter, take} from 'rxjs/operators';
|
||||||
|
|
||||||
import {NgswCommChannel} from './low_level';
|
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).
|
* [ServiceWorkerContainer#register()](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register).
|
||||||
*/
|
*/
|
||||||
scope?: string;
|
scope?: string;
|
||||||
|
|
||||||
|
registrationStrategy?: (() => Observable<any>)|string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SCRIPT = new InjectionToken<string>('NGSW_REGISTER_SCRIPT');
|
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
|
// 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.
|
// 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;
|
return initializer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ export declare class SwPush {
|
||||||
|
|
||||||
export declare abstract class SwRegistrationOptions {
|
export declare abstract class SwRegistrationOptions {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
|
registrationStrategy?: (() => Observable<any>) | string;
|
||||||
scope?: string;
|
scope?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue