Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(service-worker): add option to config when to register sw #21842

Closed
wants to merge 8 commits into from
30 changes: 15 additions & 15 deletions aio/content/guide/service-worker-getting-started.md
@@ -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

Expand All @@ -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
Expand All @@ -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`

Expand All @@ -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**.
Expand All @@ -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.

Expand Down Expand Up @@ -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`.

Expand Down Expand Up @@ -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).
62 changes: 62 additions & 0 deletions packages/examples/service-worker/registration-options/BUILD.bazel
@@ -0,0 +1,62 @@
package(default_visibility = ["//visibility:public"])

load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("//tools:defaults.bzl", "ng_module", "ts_library")
load("@npm_bazel_typescript//:index.bzl", "ts_devserver")

ng_module(
name = "sw_registration_options_examples",
srcs = glob(
["**/*.ts"],
exclude = ["**/*_spec.ts"],
),
# TODO: FW-1004 Type checking is currently not complete.
type_check = False,
deps = [
"//packages/core",
"//packages/platform-browser",
"//packages/platform-browser-dynamic",
"//packages/service-worker",
],
)

ts_library(
name = "sw_registration_options_e2e_tests_lib",
testonly = True,
srcs = glob(["**/e2e_test/*_spec.ts"]),
tsconfig = "//packages/examples:tsconfig-e2e.json",
deps = [
"//packages/examples/test-utils",
"//packages/private/testing",
"@npm//@types/jasminewd2",
"@npm//protractor",
],
)

ts_devserver(
name = "devserver",
entry_module = "@angular/examples/service-worker/registration-options/main",
index_html = "//packages/examples:index.html",
port = 4200,
scripts = [
"//tools/rxjs:rxjs_umd_modules",
"@npm//node_modules/tslib:tslib.js",
],
static_files = [
"ngsw-worker.js",
"@npm//node_modules/zone.js:dist/zone.js",
],
deps = [":sw_registration_options_examples"],
)

protractor_web_test_suite(
name = "protractor_tests",
data = ["//packages/bazel/src/protractor/utils"],
on_prepare = "start-server.js",
server = ":devserver",
deps = [
":sw_registration_options_e2e_tests_lib",
"@npm//protractor",
"@npm//selenium-webdriver",
],
)
@@ -0,0 +1,27 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../test-utils';

describe('SW `SwRegistrationOptions` example', () => {
const pageUrl = '/registration-options';
const appElem = element(by.css('example-app'));

afterEach(verifyNoBrowserErrors);

it('not register the SW by default', () => {
browser.get(pageUrl);
expect(appElem.getText()).toBe('SW enabled: false');
});

it('register the SW when navigating to `?sw=true`', () => {
browser.get(`${pageUrl}?sw=true`);
expect(appElem.getText()).toBe('SW enabled: true');
});
});
12 changes: 12 additions & 0 deletions packages/examples/service-worker/registration-options/main.ts
@@ -0,0 +1,12 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModuleNgFactory} from './module.ngfactory';

platformBrowserDynamic().bootstrapModuleFactory(AppModuleNgFactory);
49 changes: 49 additions & 0 deletions packages/examples/service-worker/registration-options/module.ts
@@ -0,0 +1,49 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
// tslint:disable: no-duplicate-imports
import {Component} from '@angular/core';
// #docregion registration-options
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {ServiceWorkerModule, SwRegistrationOptions} from '@angular/service-worker';
// #enddocregion registration-options
import {SwUpdate} from '@angular/service-worker';
// tslint:enable: no-duplicate-imports

@Component({
selector: 'example-app',
template: 'SW enabled: {{ swu.isEnabled }}',
})
export class AppComponent {
constructor(readonly swu: SwUpdate) {}
}
// #docregion registration-options

@NgModule({
// #enddocregion registration-options
bootstrap: [
AppComponent,
],
declarations: [
AppComponent,
],
// #docregion registration-options
imports: [
BrowserModule,
ServiceWorkerModule.register('ngsw-worker.js'),
],
providers: [
{
provide: SwRegistrationOptions,
useFactory: () => ({enabled: location.search.includes('sw=true')}),
},
],
})
export class AppModule {
}
// #enddocregion registration-options
@@ -0,0 +1,14 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

// Mock `ngsw-worker.js` used for testing the examples.
// Immediately takes over and unregisters itself.
self.addEventListener('install', evt => evt.waitUntil(self.skipWaiting()));
self.addEventListener(
'activate',
evt => evt.waitUntil(self.clients.claim().then(() => self.registration.unregister())));
@@ -0,0 +1,17 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

const protractorUtils = require('@angular/bazel/protractor-utils');
const protractor = require('protractor');

module.exports = async function(config) {
const {port} = await protractorUtils.runServer(config.workspace, config.server, '-port', []);
const serverUrl = `http://localhost:${port}`;

protractor.browser.baseUrl = serverUrl;
};
2 changes: 1 addition & 1 deletion packages/service-worker/src/index.ts
Expand Up @@ -15,6 +15,6 @@
*/

export {UpdateActivatedEvent, UpdateAvailableEvent} from './low_level';
export {ServiceWorkerModule} from './module';
export {ServiceWorkerModule, SwRegistrationOptions} from './module';
export {SwPush} from './push';
export {SwUpdate} from './update';