Tous les articles
Mar. 21 juillet 2026 · 5 min de lecture

🧰 Angular : le tooling clé en main, du scaffolding aux tests

Angular CLI et tooling officiel

📚 Introduction

Dans l’article précédent, je défendais l’idée qu’un framework complet coûte moins cher à maintenir qu’une pile assemblée. C’est une thèse ; passons aux faits. Concrètement, qu’est-ce qu’Angular te donne, aujourd’hui, en v22, sans que tu n’installes rien de plus ?

J’ai fait le tour des briques officielles avec la doc ouverte à côté, parce que l’Angular de 2026 n’a plus grand-chose à voir avec celui dont beaucoup gardent le souvenir. Voici ce que ça donne, de la création du projet au serveur MCP.

Ce que couvre la CLI Angular sur le cycle de vie d'un projet, du scaffolding à la montée de version

🚀 Une CLI qui couvre tout le cycle

Tout part de ng. Création du projet, avec le rendu serveur activé d’entrée :

ng new mon-app --ssr

Puis le quotidien :

ng generate component facture-liste
ng serve
ng build
ng test

Et surtout les deux commandes qui font la différence sur la durée :

# ajoute une brique officielle et exécute son schematic d'installation
ng add @angular/ssr
 
# monte les paquets Angular ET applique les migrations de code
ng update @angular/core @angular/cli

ng update n’est pas un npm update déguisé. Il exécute des transformations de code : renommages d’API, réécritures de configuration, adaptations de templates. Angular impose de monter une majeure à la fois, et c’est un bon rappel : la commande n’est pas magique, elle est incrémentale.

🧱 DI, HTTP : le socle

L’injection de dépendances est native, avec un vrai conteneur. La v22 introduit le décorateur @Service, qui remplace avantageusement le @Injectable({ providedIn: 'root' }) qu’on écrivait mécaniquement :

import { Service, inject, signal } from '@angular/core';
 
@Service()
export class PanierStore {
	private readonly http = inject(HttpClient);
	private readonly lignes = signal<Ligne[]>([]);
 
	readonly contenu = this.lignes.asReadonly();
 
	ajouter(ligne: Ligne) {
		this.lignes.update((lignes) => [...lignes, ligne]);
	}
}

Côté réseau, httpResource() enveloppe HttpClient et expose l’état de la requête sous forme de signaux. La requête est réactive : quand un signal dont elle dépend change, elle repart, et la requête précédente est annulée si elle est encore en vol.

userId = input.required<string>();
 
user = httpResource(() => `/api/user/${userId()}`);

Dans le template, on lit les signaux directement :

@if (user.hasValue()) {
	<user-details [user]="user.value()" />
} @else if (user.error()) {
	<div>Impossible de charger l'utilisateur</div>
} @else if (user.isLoading()) {
	<div>Chargement…</div>
}

À noter : httpResource est fait pour la lecture. Pour un POST ou un PUT, on reste sur HttpClient.

🛠️ Formulaires et accessibilité

Les Signal Forms sont passées en API publique en v22, dans le sous-chemin @angular/forms/signals. Le modèle est un signal, le schéma de validation est déclaré à part :

import { form, schema, required, email, minLength } from '@angular/forms/signals';
 
const contactSchema = schema<Contact>((path) => {
	required(path.nom);
	minLength(path.nom, 2);
	required(path.email);
	email(path.email);
});
 
export class ContactPage {
	readonly modele = signal<Contact>({ nom: '', email: '' });
	readonly contact = form(this.modele, contactSchema);
}

Et côté template, deux directives suffisent :

<form [formRoot]="contact">
	<input [formField]="contact.nom" />
	<input [formField]="contact.email" />
</form>

Les formulaires réactifs historiques ne disparaissent pas — c’est bien le principe de la politique de dépréciation d’Angular, on y revient dans le prochain article.

Sur l’accessibilité, @angular/aria a été stabilisé en v22 : des primitives de composants accessibles (clavier, lecteurs d’écran) à styler soi-même, sans imposer Material.

🧪 Tester sans rien installer ?

Oui, depuis la v21. La CLI configure Vitest et jsdom sur les nouveaux projets, et ng test lance directement Vitest en mode watch :

ng test

Les tests tournent dans Node avec jsdom pour simuler le DOM, ce qui évite le coût de démarrage d’un vrai navigateur. On peut remplacer jsdom par happy-dom — ce sont les deux implémentations supportées. Karma reste supporté pour les projets historiques, et une migration automatique est fournie pour passer de l’un à l’autre.

C’est un changement notable : pendant des années, « configurer les tests » était le premier ticket d’un nouveau projet frontend. Là, c’est déjà fait.

🎯 SSR et hydratation

Le rendu serveur est officiel et se configure route par route, dans un app.routes.server.ts :

import { RenderMode, ServerRoute } from '@angular/ssr';
 
export const serverRoutes: ServerRoute[] = [
	{
		path: '',
		renderMode: RenderMode.Client
	},
	{
		path: 'facture/:id',
		renderMode: RenderMode.Server
	}
];

Par défaut, Angular prérend l’application et génère un fichier serveur. Pour un site entièrement statique, on passe outputMode à static — un fonctionnement qui rappellera quelque chose à ceux qui ont lu mes notes sur la migration Astro 5 vers Astro 6.

🤖 Le serveur MCP officiel

La CLI embarque un serveur MCP (expérimental) qui expose ses outils aux assistants de code. On le branche à son hôte avec cette configuration :

{
	"mcpServers": {
		"angular-cli": {
			"command": "npx",
			"args": ["-y", "@angular/cli", "mcp"]
		}
	}
}

Un flag --read-only permet de n’enregistrer que les outils en lecture seule — utile si tu ne veux pas qu’un agent lance des schematics tout seul. C’est la même tendance que celle que j’observais côté PHP avec Laravel Boost : les frameworks livrent désormais leur propre contexte aux agents plutôt que de les laisser deviner.

⚠️ Quelques précautions

  • Le serveur MCP est expérimental. Ne construis pas un workflow d’équipe dessus en supposant que la surface d’outils est figée.
  • ng update ne dispense pas de relire le diff. Les migrations sont bonnes, elles ne sont pas infaillibles, et certaines ne peuvent pas couvrir le code trop dynamique.
  • Signal Forms ne remplace pas tout du jour au lendemain. Sur une application existante avec cent formulaires réactifs, la migration se planifie, elle ne se décrète pas.
  • Le passage à Vitest est confortable sur un projet neuf ; sur un projet Karma/Jasmine chargé en helpers maison, la migration automatique fait le gros du travail mais laisse des restes à traiter à la main.

🎉 Conclusion

Ce qui me frappe en refaisant ce tour, ce n’est pas qu’une brique en particulier soit brillante. C’est l’absence de trou. Routing, HTTP, formulaires, validation, accessibilité, SSR, tests, montée de version, contexte pour les agents : tout est là, sous le même numéro de version, testé ensemble avant chaque release.

C’est très exactement le confort que je retrouve côté PHP avec Symfony ou Laravel, et qui manque cruellement quand on assemble sa propre pile frontend.

Dans le dernier article de la série, je regarde ce qui a changé récemment dans le framework lui-même : zoneless, signals, et surtout le passage à un cycle de releases annuel — qui change le calcul de maintenance sur un projet client.

🔗 Liens utiles

/faq

Questions fréquentes

Que fait la commande ng update ?

+

Elle met à jour les paquets Angular d'un projet et applique les migrations de code correspondantes : renommages d'API, changements de configuration, adaptations de templates. On monte une seule version majeure à la fois.

Angular impose-t-il encore Karma pour les tests ?

+

Non. Depuis la v21, la CLI configure Vitest et jsdom sur les nouveaux projets, et `ng test` lance Vitest. Karma reste supporté pour les projets historiques, et une migration automatique est fournie.

Faut-il une bibliothèque tierce pour faire du SSR en Angular ?

+

Non. Le rendu serveur est officiel : `ng new --ssr` sur un nouveau projet, ou `ng add @angular/ssr` sur un projet existant. Les stratégies de rendu se déclarent route par route via `RenderMode`.

Angular fournit-il un serveur MCP pour les assistants IA ?

+

Oui, la CLI embarque un serveur MCP expérimental lancé par `ng mcp`, que l'on branche à son assistant avec la commande `npx -y @angular/cli mcp`. Un flag `--read-only` limite l'exposition aux outils en lecture seule.