Getting Started
Update the CLI to latest version
sudo npm install -g @angular/cli
Change to parent directory and start dev server
ng new PROJECT_NAME --style=scss
cd PROJECT_NAME
ng serve --port 4200
Point browser to http://localhost:4200 to make sure "app works!"
Install Basic and UI dependencies
sudo npm install --save @angular/material hammerjs @angular/flex-layout rxjs @angular/animations \
@angular/service-worker ng-pwa-tools @angular/platform-server
Install Firebase and AngularFire2 dependencies
sudo npm install --save firebase angularfire2
Enable service worker and push notifications
main.ts
platformBrowserDynamic()
.bootstrapModule(AppModule)
.then(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/worker-basic.min.js');
}
});
Tell angular-cli to build the project with service worker
ng set apps.0.serviceWorker=true
app.module.ts
import {NgServiceWorker, ServiceWorkerModule} from '@angular/service-worker';
imports: [
BrowserModule.withServerTransition({appId: 'app-name'}),
RouterModule.forRoot([...]),
ServiceWorkerModule,
…
]
export class AppModule {
constructor(sw: NgServiceWorker) {
sw.registerForPush({
applicationServerKey: '<YOUR-FCM-API-KEY>'
}).subscribe(sub => {
console.log(sub.toJSON());
});
sw.push.subscribe(msg => {
console.log('got push message', msg);
});
}
}
Gotcha - add module.id to your components and set your routes
(otherwise your manifest generation may FAIL)
moduleId: module.id
Build the app
ng build --prod
Generate manifest
./node_modules/.bin/ngu-sw-manifest --module src/app/app.module.ts
Create ngsw-manifest.json file in src folder
Note: change "freshness" to "performance" if your app doesn't need realtime
{
"dynamic": {
"group": [
{
"name": "firebase",
"urls": {
"<YOUR-FIREBASE-HOSTING-URL>": {
"match": "prefix"
}
},
"cache": {
"optimizeFor": "freshness",
"maxAgeMs": 3600000,
"maxEntries": 20,
"strategy": "lru"
}
}
]
},
"push": {
"showNotifications": true
}
}
Generate Loading module
ng g module Loading
Generate static app shell loading route
Note: make sure your exists in app.component.html
./node_modules/.bin/ngu-app-shell --module src/app/app.module.ts --url /loading --insert-module src/app/loading/loading.module.ts
Set up firebase HTTP/2 push
./node_modules/.bin/ngu-firebase-push --module src/app/app.module.ts
Full run.sh script
Note: you may need to add permission to the file: chmod +x run.sh
#!/bin/bash
PATH=$PATH:$(npm bin)
set -x
# Production build
ng build --prod
# Generate a new index.html with an app shell
./node_modules/.bin/ngu-app-shell --module src/app/app.module.ts \
--url /loading \
--insert-module src/app/loading/loading.module.ts \
--out dist/index.html
# Generate a SW manifest from our app
./node_modules/.bin/ngu-sw-manifest --module src/app/app.module.ts \
--out dist/ngsw-manifest.json
# Copy prebuilt worker into our site
cp node_modules/@angular/service-worker/bundles/worker-basic.min.js dist/
# Serve
cd dist
http-server
Full deploy.sh script
Note: you may need to add permission to the file: chmod +x run.sh
#!/bin/bash
PATH=$PATH:$(npm bin)
set -x
# Production build
ng build --prod
# Generate a new index.html with an app shell
./node_modules/.bin/ngu-app-shell --module src/app/app.module.ts \
--url /loading \
--insert-module src/app/loading/loading.module.ts \
--out dist/index.html
# Generate a SW manifest from our app
./node_modules/.bin/ngu-sw-manifest --module src/app/app.module.ts \
--out dist/ngsw-manifest.json
# Copy prebuilt worker into our site
cp node_modules/@angular/service-worker/bundles/worker-basic.min.js dist/
# Deploy
firebase deploy
Run PWA build script and server
./run.sh
Deploy your app
./deploy.sh
To see script output and service worker state http://localhost:4200/ngsw.log http://localhost:4200/ngsw-manifest.json
References
Google Developers: Debugging Service Workers
Transforming an existing Angular application into a Progressive Web App