Maxim Salnikov
Angular GDE
How to create an Angular Progressive Web App?
March 1-2, Helsinki
8 Nov, 13:20, "Mars"
22 events / 2 hackathons
... attempts to combine features offered by most modern browsers with the benefits of mobile experience
... web apps that use the latest web technologies.
Progressive
Discoverable
Linkable
App-like
Responsive
Connectivity-independent
Re-engageable
Installable
Fresh
Safe
App
Service worker
$ ng new myProgressiveApp --service-worker
$ ng build --prod
$ ng set apps.0.serviceWorker=true
$ npm install @angular/service-worker --save
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
...
@NgModule({
...
imports: [
...
]
})
export class AppModule { }
environment.production ?
ServiceWorkerModule.register('/ngsw-worker.js') : []
{
"index": "/index.html",
"assetGroups": [...],
"dataGroups": [...]
}
{
"name": "app",
"installMode": "prefetch",
"resources": {...}
}
"resources": {
}
"versionedFiles": [
"/*.bundle.css",
"/*.bundle.js",
"/*.chunk.js"
],
"files": [
"/favicon.ico",
"/index.html"
],
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {...}
}
"resources": {
}
"files": [
"/assets/**"
],
"urls": [
"https://fonts.googleapis.com/**",
"https://fonts.gstatic.com/**"
]
{
"name": "api-freshness",
"urls": [
"/api/breakingnews/**"
],
}
"cacheConfig": {
"strategy": "freshness",
"maxSize": 10,
"maxAge": "12h",
"timeout": "10s"
}
{
"name": "api-performance",
"urls": [
"/api/archive/**"
],
}
"cacheConfig": {
"strategy": "performance",
"maxSize": 100,
"maxAge": "365d"
}
"ngsw-config": "node_modules/.bin/ngsw-config dist src/ngsw-config.json"
"ngsw-copy": "cp node_modules/@angular/service-worker/ngsw-worker.js dist/"
"build-ngsw": "ng build --prod && npm run ngsw-config && npm run ngsw-copy"
import { SwPush } from '@angular/service-worker';
constructor(private swPush: SwPush) {}
subscribeToPush() {
this.swPush.requestSubscription({
serverPublicKey: this.VAPID_PUBLIC_KEY
})
.then(pushSubscription => {
// Pass subscription object to backend
})
}
{
"notification": {
}
}
"title": "Very important notification",
"body": "Angular Service Worker is cool!",
"icon": "https://angular.io/assets/logo.png",
"actions": [
{
"action": "gocheck",
"title": "Go and check"
}
],
...
import { SwUpdate } from '@angular/service-worker';
constructor(private swUpdate: SwUpdate) {}
this.swUpdate.available.subscribe(event => {
let snackBarRef = this.snackBar
.open('Newer version of the app is available', 'Refresh');
snackBarRef.onAction().subscribe(() => {
window.location.reload()
})
})