Comment créer une application angulaire avec un rendu côté serveur

Il existe plusieurs raisons pour lesquelles vous pouvez utiliser le rendu côté serveur avec votre application Angular.

  1. SSR aide à l'optimisation des moteurs de recherche. Les moteurs de recherche peuvent analyser la page car elle est rendue sur le serveur.
  2. Les plateformes médiatiques de Socia telles que Facebook et Twitter peuvent afficher un aperçu du site lorsqu'elles sont partagées.
  3. Une fois qu'une page Web est affichée sur le serveur, vous pouvez la mettre en cache et la servir beaucoup plus rapidement.

Pour implémenter le rendu côté serveur dans votre application Angular, vous pouvez utiliser le package Angular Universal.

Univers angulaire

Créer un nouveau projet angulaire:

ng nouveau nom de projet

Dans ce projet, téléchargez les packages suivants et ajoutez Angular Universal:

cd nom-projet
npm install --save @ angular / platform-server @ nguniversal / module-map-ngfactory-loader ts-loader@3.5.0 express
ng générer un nom de projet universel

Cela crée et met à jour les fichiers suivants:

créer src / app / app.server.module.ts
créer src / main.server.ts
créez src / tsconfig.server.json
mettre à jour package.json
mise à jour .angular-cli.json
mettre à jour src / main.ts
mettre à jour src / app / app.module.ts
mettre à jour .gitignore

Modules: Vous avez maintenant deux modules racine distincts: app.server.module.ts et app.module.ts. Le module serveur importe ServerModule à partir du package @ angular / platform-server. Le module de navigateur appelle la méthodeBrowerModule.withServerTransition () qui indique à Angular que nous utilisons le rendu côté serveur et que la vue doit être permutée une fois que la structure complète est chargée.

Point d'entrée: vous avez également deux points d'entrée pour votre application: src / main.ts et src / main.server.ts. Ce dernier est le point d’entrée du serveur et exporte simplement notre module de serveur.

Fichiers de configuration: Pour indiquer au compilateur Angular que nous avons deux modules d'entrée, le fichier tsconfig.server.json est créé. Tsconfig.app.json compile l'application du navigateur.

CLI angulaire: dans le fichier angular-cli.json, un deuxième profil est ajouté pour le groupe de serveurs.

Bootstrapping: votre fichier main.ts est mis à jour avec la fonction suivante:

document.addEventListener ('DOMContentLoaded', () => {
   platformBrowserDynamic (). bootstrapModule (AppModule)
   .catch (err => console.log (err));
});

Cela permet de s'assurer que l'application Angular est démarrée après le chargement du DOM. La logique d'amorçage d'application est placée dans l'événement DOMContentLoaded.

Serveur de nœud

Ensuite, vous devrez créer un serveur dans le répertoire racine de l'application. Ce fichier utilisera le fichier Javascript produit en exécutant npm run build: ssr à l'aide de l'application serveur configurée dans le fichier .angular-cli.json. Il est ensuite appliqué à la page index.html. Créez un fichier server.ts dans le répertoire racine de votre projet et ajoutez le code suivant:

Le fichier server.ts nécessite une configuration Webpack pour générer le fichier Javascript à exécuter sur le serveur. Créez un fichier webpack.server.config.js dans le répertoire racine de votre application et ajoutez le code suivant:

Dans votre fichier package.json, ajoutez les commandes suivantes à votre tableau de scripts:

"build: ssr": "npm run build: ensembles client-serveur && npm run webpack: serveur",
"serve: ssr": "node dist / server.js",
"build: client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing = false",
"webpack: serveur": "webpack --config webpack.server.config.js --progress --colors"

Première exécution de npm run build: ssr et lorsque cela est terminé, exécutez npm run serve: ssr. Votre demande doit être signifiée à localhost: 4201.

État de transfert

Lorsque nous utilisons Angular Universal, l’API qui fournit le contenu est frappée deux fois. D'abord lorsque le serveur rend la page et deuxièmement, lorsque l'application est démarrée. Cela provoque des problèmes de latence et une mauvaise expérience utilisateur car l'écran scintille généralement lorsque cela se produit. Voir le schéma ci-dessous pour voir comment cela fonctionne:

conçu par Upstate Interactive, LLC

Nous pouvons utiliser le service TransferState pour envoyer des informations du serveur au client, ce qui évite de faire des appels d'API en double. Voyez comment cela fonctionne ci-dessous:

conçu par Upstate Interactive, LLC

Utilisons le service TransferState dans notre application. Dans app.module.ts, importez le BrowserTransferStateModule:

importer {BrowserModule, BrowserTransferStateModule} depuis '@ angular / platform-browser';
importations: [
  BrowserModule.withServerTransition ({appId: 'my-app'}),
  BrowserTransferStateModule,
  ...
]

Dans app.server.module.ts, importez le ServerTransferStateModule:

importer {ServerModule, ServerTransferStateModule} de '@ angular / platform-server';
importations: [
  AppModule,
  ServerModule,
  ServerTransferStateModule,
  ...
]

Nous pouvons utiliser la fonction makeStateKey pour créer une clé, pour stocker des données dans l'état (qui seront transmises au navigateur). Vous utiliserez this.state.get pour obtenir des données de l'état et this.state.set pour définir des données dans l'état. Lorsqu'un appel d'API est effectué, vous stockez les données renvoyées dans l'état à l'aide de la clé créée avec makeStateKey.

Dans le fichier utilisé par votre API, importez les modules TransferState et makeStateKey.

import {TransferState, makeStateKey} à partir de '@ angular / platform-browser';

Injectez le service TransferState dans votre fonction constructeur:

constructeur(
   Etat privé: TransferState,
   ...
) {}

Créez des clés pour stocker vos données:

const KEY_NAME = makeStateKey ('nom_variable');

Dans votre fonction dans laquelle vous appelez une API, obtenez vos données de l'état à l'aide de this.state.get. Si l'entrée n'est pas trouvée, passez votre appel http. Lorsque vous récupérez vos données à partir de l'appel http, stockez-les dans l'état à l'aide de this.state.set.

functionName () {
   let nom_variable = this.state.get (KEY_NAME, null en tant que tout);
   if (nom_variable) {
     return Observable.of (nom_variable);
   }
   renvoie this.http.get ('url')
     ...
     this.state.set (KEY_NAME, nom_variable, le cas échéant);
     return nom_variable;
 }

Désormais, votre client ne passera pas d'appel HTTP lorsque les données seront renvoyées par le serveur de rendu, car elles sont stockées dans l'état.

Si vous exécutez votre application après avoir suivi ces étapes, votre application ne passera aucun appel HTTP à partir du client. Vous pouvez le confirmer en consultant l'onglet Réseau dans les outils de développement de votre navigateur. Vous ne devriez voir aucune requête XHR, car celle-ci est en cours de création sur le serveur et envoyée au navigateur au format HTML.

Enfin, toutes les applications ne justifient pas le rendu côté serveur. Plutôt que de l'expliquer moi-même, je vous recommande de lire cet article pour avoir un aperçu complet du moment où la SSR convient à votre projet. En outre, une bonne partie de ma compréhension de ce sujet provient de la suite du tutoriel suivant: http://www.dotnetcurry.com/angularjs/1388/server-side-rendering-angular-nodejs. Je recommande vivement de suivre et de créer l'application vous-même.

Pour aller plus loin, consultez la Partie II: Configuration d’Angular Universal avec ngrx.

J'espère que cela a été utile!

☞ Nous aidons les organisations B2B à transformer de bonnes idées en logiciels. Envie d'en savoir plus?

☞ Les articles suivants peuvent également vous intéresser.