Progressive Web App avec Angular 8

14/11/19 dannyEnglish Version

Qu'allons nous faire ?

Nous allons faire de notre Application Web standard une PWA (Progressive Web App )
Nous utiliserons le framework javascript Angular version 8.2.14

Il s'agit de l'étape 8 de notre guide Angular qui nous permettra d'obtenir une Application Web de type PWA.Le projet Angular de base que nous utiliserons dispose déjà des caractéristiques suivantes

  • Généré avec Angular CLI
  • Le Routing
  • Le Lazy Loading
  • Le framework CSS Bootstrap
  • Server Side Rendering
  • HttpClient
  • Transfer State

Tous les sources créés sont indiqués en fin de tutoriel.

L' application est à l'adresse suivante 


Avant de commencer

2008 App Store est un magasin d'applications distribué par Apple sur les appareils mobiles fonctionnant sous iOS. 
2012 Google Play Store est un magasin d'applications en ligne créé par Google. 

2014, les ventes mondiales annuelles de smartphones dépassent le milliard d'unités.

2017 deux systèmes d’exploitation pour mobile se partage le marché mondial des smartphones.
Android 85.1 %  et IOS 14.8%

Plus de 50% des recherches internet sont dorénavant effectuées sur mobile en France. 

Les systèmes d’exploitation Android et iOS sont écrits dans des langages de programmation différents.
Les applications iOS fonctionnent ainsi sur Objective-C / Swift, tandis que les applications Android fonctionnent sur Java.

Si vous voulez développez une application mobile , vous pouvez soit développer une version spécifique pour chaque plateforme ou utiliser un outil cross plateform qui vous permettra de n'avoir qu'un seul source pour les deux OS.
Il faudra néammoins gèrer l'inscription sur les app store.
Dans tous les cas les utilisateurs doivent aller sur une plateforme de téléchargement pour installer une appli.

En 2015, Frances Berriman et l’ingénieur de Google Alex Russell proposent le terme de  "progressive web apps" 

Une PWA se consulte comme un site web classique, depuis une URL sécurisée mais permet une expérience utilisateur similaire à celle d'une application mobile, sans les contraintes de cette dernière (soumission aux App-Stores, utilisation importante de la mémoire de l'appareil…).


Initialisation

Nous utiliserons la documentation Angular pour appliquer cette technique.
https://angular.io/guide/service-worker-intro

Nous utiliserons la commande angular-cli
ng add

# Ajout de la librairie pwa
ng add @angular/pwa --project angular-starter

Angular-cli a procédé automatiquement à un certain nombre de modifications sur notre projet.

  • modification du fichier package.json ( dans cet exemple nous mettrons à jour les dépendances et les descripteurs)
  • modification du fichier angular.json
  • création du fichier ngsw-config.json
  • création du fichier src/manifest.webmanifest
  • modification du fichier src/index.html
  • modification du fichier src/app.browser.module.ts
  • création des icônes src/app/assets/icons
package.json
  "dependencies": {
    "@angular/animations": "8.2.14",
    "@angular/common": "8.2.14",
    "@angular/compiler": "8.2.14",
    "@angular/core": "8.2.14",
    "@angular/forms": "8.2.14",
    "@angular/platform-browser": "8.2.14",
    "@angular/platform-browser-dynamic": "8.2.14",
    "@angular/platform-server": "8.2.14",
    "@angular/pwa": "0.803.19",
    "@angular/router": "8.2.14",
    "@angular/service-worker": "8.2.14",
    "@fortawesome/fontawesome-free": "5.11.2",
    "@nguniversal/express-engine": "8.1.1",
    "@nguniversal/module-map-ngfactory-loader": "8.1.1",
    "bootstrap": "4.3.1",
    "express": "4.17.1",
    "jquery": "3.4.1",
    "rxjs": "6.5.3",
    "tslib": "1.10.0",
    "zone.js": "0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "0.803.19",
    "@angular/cli": "8.3.19",
    "@angular/compiler-cli": "8.2.14",
    "@angular/language-service": "8.2.14",
    "@types/node": "12.12.7",
    "@types/jasmine": "3.4.6",
    "@types/jasminewd2": "2.0.8",
    "codelyzer": "5.2.0",
    "jasmine-core": "3.5.0",
    "jasmine-spec-reporter": "4.2.1",
    "karma": "4.4.1",
    "karma-chrome-launcher": "3.1.0",
    "karma-coverage-istanbul-reporter": "2.1.0",
    "karma-jasmine": "2.0.1",
    "karma-jasmine-html-reporter": "1.4.2",
    "protractor": "5.4.2",
    "ts-loader": "6.2.1",
    "ts-node": "8.5.0",
    "tslint": "5.20.1",
    "typescript": "3.5.3",
    "webpack-cli": "3.3.10"
  }
angular.json
{

"assets": [
  "src/favicon.ico",
  "src/assets",
  "src/manifest.webmanifest"
],

........


"configurations": {
  "production": {
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ],
    "optimization": true,
    "outputHashing": "all",
    "sourceMap": false,
    "extractCss": true,
    "namedChunks": false,
    "aot": true,
    "extractLicenses": true,
    "vendorChunk": false,
    "buildOptimizer": true,
    "budgets": [
      {
        "type": "initial",
        "maximumWarning": "2mb",
        "maximumError": "5mb"
      },
      {
        "type": "anyComponentStyle",
        "maximumWarning": "6kb",
        "maximumError": "10kb"
      }
    ],
    "serviceWorker": true,
    "ngswConfigPath": "ngsw-config.json"
  }
}
ngsw-config.json
{
  "$schema": "./node_modules/@angular/service-worker/config/schema.json",
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/manifest.webmanifest",
          "/*.css",
          "/*.js"
        ]
      }
    }, {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
        ]
      }
    }
  ]
}
src/manifest.webmanifest
{
  "name": "angular-starter",
  "short_name": "angular-starter",
  "theme_color": "#1976d2",
  "background_color": "#fafafa",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "icons": [
    {
      "src": "assets/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}
src/index.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularStarter</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="manifest" href="manifest.webmanifest">
  <meta name="theme-color" content="#1976d2">
</head>
<body>
  <app-root></app-root>
  <noscript>Please enable JavaScript to continue using this application.</noscript>
</body>
</html>
src/app.browser.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';

@NgModule({
  imports: [
    AppModule,
    BrowserModule.withServerTransition({ appId: 'angular-starter' }),
    BrowserTransferStateModule,
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
  ],
  bootstrap: [AppComponent],
})
export class AppBrowserModule { }

Conclusion

Nous allons tester le fonctionnement de la PWA

Le script npm run start execute la commande ng serve   
ng serve ne fonctionne pas avec les service workers

Pour tester il faut utiliser un server http.

Les scripts suivants pemettent donc de tester notre pwa

  • npm run build:ssr
  • npm run serve:ssr
  • http://localhost:4000/

 

Il ne reste qu'à ouvrir les outils de développement Chrome avec Ctrl + Maj + J
Et executer un test de l'outil Lighthouse

  • Audits
  • Run audits

Laissez un commentaire

Votre avis
Cette adresse ne sera pas publiée