Cours Angular · Module 14: Patterns avancés
La voie de la lame vers le champ de bataille - SSR et déploiement
Dans cette leçon5
Ton application est prête dans le dojo - mais un vrai samouraï ne reste pas dans la salle d'entraînement. Cette leçon est la voie de la lame vers le combat : tu vas d'abord décider comment chaque page est forgée (le rendu), puis forger la lame finie (le build), et enfin l'envoyer dans le monde (le déploiement). Nous franchirons ces portes une par une.
Première porte : où naît la page (SSR)
Par défaut, Angular assemble la page seulement dans le navigateur du visiteur - c'est comme lui tendre de l'acier brut et lui demander de forger le sabre lui-même. Sur un appareil lent, le visiteur fixe longtemps un écran vide, et les moteurs de recherche ne voient que du vide. Le rendu côté serveur (Server-Side Rendering, SSR) déplace la forge sur le serveur : le HTML est rendu sur le serveur et le balisage prêt est envoyé au navigateur, si bien que le visiteur reçoit une page complète tout de suite.
1# Ajouter le SSR au projet existant
2ng add @angular/ssr
3
4# Ou directement pour un nouveau projet
5ng new my-app --ssrUne seule commande, ng add @angular/ssr, installe tout le nécessaire - le serveur, la configuration et les points d'entrée. Retiens bien cette forme exacte : ce n'est pas ng generate ssr (aucun schematic ne porte ce nom), ni npm install ssr (aucun paquet ne s'appelle ainsi, et un simple install ne configurerait rien), ni ng build --ssr - le build vient bien plus loin sur la voie et ne sert jamais à ajouter le SSR.
Une fois l'installation faite, le cœur du SSR tient dans un seul provider qui dit à Angular de rendre aussi côté serveur :
1// app.config.server.ts
2import { ApplicationConfig, mergeApplicationConfig } from '@angular/core';
3import { provideServerRendering } from '@angular/platform-server';
4import { appConfig } from './app.config';
5
6const serverConfig: ApplicationConfig = {
7 providers: [
8 provideServerRendering()
9 ]
10};
11
12export const config = mergeApplicationConfig(appConfig, serverConfig);Remarque mergeApplicationConfig - nous ne créons pas une application distincte pour le serveur, nous ajoutons les réglages serveur à la configuration commune venue de app.config.ts. La même application tourne ainsi dans le navigateur et sur le serveur, sans deux bases de code à entretenir.
Un piège accompagne cette forge côté serveur : sur le serveur, il n'existe ni window ni localStorage. Remets aussi les notions en place au passage - effectuer le rendu de l'application exclusivement côté navigateur, c'est le comportement par défaut que tu viens justement de quitter ; stocker l'état de l'application dans localStorage ou compiler les templates pendant l'exécution de l'application ne sont pas davantage du SSR. Pour que ton code survive aux deux plateformes, Angular fournit le token PLATFORM_ID (depuis @angular/core) et les gardes isPlatformBrowser() et isPlatformServer() (depuis @angular/common) : tu entoures chaque accès au stockage d'un if (isPlatformBrowser(this.platformId)), et la lame ne se brise plus au rendu serveur.
Deuxième porte : forger d'avance ce qui ne change pas (SSG)
Le SSR forge la page à chaque requête. Mais une page À propos ou la fiche d'un samouraï est identique pour tout le monde - pourquoi la reforger sans cesse ? Le prérendu (SSG) consiste à générer des pages HTML statiques au moment du build de l'application, une fois pour toutes, et à les enregistrer comme de vrais fichiers HTML.
1// angular.json
2{
3 "architect": {
4 "prerender": {
5 "builder": "@angular/build:prerender",
6 "options": {
7 "routes": [
8 "/",
9 "/about",
10 "/samurai/1",
11 "/samurai/2"
12 ]
13 }
14 }
15 }
16}Dans le champ routes, tu listes les chemins à forger d'avance. C'est la page la plus rapide possible : le serveur ne calcule rien, il tend le fichier déjà prêt. Ne confonds pas le prérendu avec les autres optimisations - il ne supprime pas le code inutilisé du bundle (ça, c'est le tree-shaking, que fait le build), il ne compresse pas les images, et il ne rend surtout pas les pages uniquement après un clic de l'utilisateur, puisque tout est forgé avant même la première visite. La règle de choix est simple : les pages identiques pour tous vont au prérendu, les pages qui dépendent du visiteur connecté restent au SSR.
L'armure pour les jours sans réseau : PWA
Un vrai guerrier combat même quand le ravitaillement manque. Une PWA (Progressive Web App) est l'armure grâce à laquelle ton application fonctionne aussi sans internet - le navigateur garde ses ressources en mémoire.
1ng add @angular/pwaComme pour le SSR, une seule commande enfile toute l'armure, et son ordre est immuable : ng, puis add, puis le paquet @angular/pwa. Le cœur d'une PWA est le service worker - le garde qui intercepte les requêtes et sert les ressources mises en cache quand le réseau vient à manquer :
1// Enregistrement du service worker
2import { isDevMode } from '@angular/core';
3import { provideServiceWorker } from '@angular/service-worker';
4
5export const appConfig: ApplicationConfig = {
6 providers: [
7 provideServiceWorker('ngsw-worker.js', {
8 enabled: !isDevMode(),
9 registrationStrategy: 'registerWhenStable:30000'
10 })
11 ]
12};La clé, c'est enabled: !isDevMode() - le garde ne veille qu'en production. C'est parfaitement voulu : au dojo, pendant le développement, tu veux voir chaque modification immédiatement, alors qu'un service worker qui met tout en cache te servirait d'anciennes versions et te tromperait.
Troisième porte : forger la lame finie (le build)
Avant d'envoyer l'application dans le monde, il faut la forger en version de combat, et l'ordre des étapes ne se discute pas : tu écris d'abord le code de l'application, puis tu lances ng build --configuration=production, qui rassemble tout le code, supprime les fragments inutiles et optimise le poids final.
1# Build de production avec optimisations
2ng build --configuration=production
3
4# Build avec rapport sur le poids du bundle
5ng build --stats-json
6npx webpack-bundle-analyzer dist/browser/stats.json
7
8# Voir le build en local
9npx http-server dist/browserLa première commande génère les fichiers dans le dossier dist/ - plus précisément dist/browser - et c'est là que repose ta lame finale. La deuxième est l'habitude du guerrier mûr : webpack-bundle-analyzer dessine la carte des bibliothèques qui pèsent le plus lourd, et avant que le visiteur ne le ressente comme une lenteur, toi tu sais déjà quoi tailler. La troisième te laisse examiner le résultat en local, exactement tel que le monde le verra.
Dernière porte : envoyer la lame dans le monde (le déploiement)
La lame est forgée - place au champ de bataille. Le déploiement sur une plateforme est la dernière étape de la voie : envoyer le contenu de dist/browser vers un service qui l'ouvrira au monde. Chacune des plateformes populaires s'en charge en une ou deux commandes :
1# Vercel
2npm i -g vercel
3vercel
4
5# Netlify
6npm i -g netlify-cli
7netlify deploy --prod
8
9# Firebase
10ng add @angular/fire
11ng deployLes trois fonctionnent de la même manière : tu installes l'outil de la plateforme, et une commande unique envoie le build déjà prêt. Le choix tient surtout au compte que tu possèdes déjà - retiens simplement qu'une application avec SSR exige une plateforme capable d'exécuter Node (Vercel, Netlify), tandis que des pages purement prérendues se contentent de n'importe quel hébergement de fichiers.
De cette leçon, garde la voie plutôt que les commandes : tu décides d'abord comment naît la page (SSR pour ce qui dépend du visiteur, SSG pour ce qui ne bouge jamais), tu la forges ensuite avec ng build --configuration=production dans le dossier dist/, et tu la déploies enfin sur une plateforme en une seule commande. C'est la même voie pour toute application Angular.
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quelle commande ajoute le rendu côté serveur (SSR) à un projet Angular ?
2. En quoi consiste le rendu côté serveur (Server-Side Rendering, SSR) dans Angular ?
Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.
Tâches pratiques dans le jeu
- Tri horizontal
Ordonne sur une seule ligne la commande qui ajoute le support PWA au projet :
- Éditeur de code
Complète le service qui utilise localStorage de façon sûre sous SSR.
- Tri vertical
Ordonne les étapes de préparation d'une application Angular pour le déploiement (du premier au dernier) :