Introduction
Le 8 novembre 2023 marque une étape importante avec la sortie d'Angular version 17, signant ainsi une renaissance pour ce framework lancé en septembre 2016. Bien qu'il ne s'agisse pas d'une réécriture totale, cette version introduit des fonctionnalités significatives. Tirant parti des dernières avancées des navigateurs, elle dote Angular d'une performance accrue. La question se pose alors : en quoi cette mise à jour constitue-t-elle un tournant décisif pour Angular ? Quels éléments rendent cette version particulièrement remarquable ?
Un tout nouveau branding
Suite à quelques jours de suspense durant lesquels le logo d'Angular a été mystérieusement remplacé par un point d'interrogation sur des réseaux sociaux, notamment le très connu X, l'équipe Angular a révélé le lundi 6 novembre un tout nouveau logo ainsi qu'une version entièrement rénovée de leur site de documentation.
Ce site récemment lancé, encore en développement notamment au niveau des APIs, propose des améliorations significatives. Parmi celles-ci, on trouve :
- La possibilité de tester des fonctionnalités dans un environnement sandbox,
- La possibilité de découvrir de nouveaux tutoriels interactifs également accessibles via ce sandbox
- Une organisation revue et corrigée autour de thématiques ciblées telles que les composants, les formulaires, l'accessibilité et les meilleures pratiques.
Je vous invite à explorer ce site et à faire part de vos impressions, questions ou éventuelles erreurs rencontrées.
L'anotation @Component
La notation @Component a été légèrement améliorée. Historiquement, avec Angular, il était nécessaire de fournir un tableau de chemins relatifs aux feuilles de style pour associer des styles à nos composants, comme ceci :
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {}
En général, une vue est associée à une feuille de style. Dans cette optique, une propriété styleUrls
est utilisée pour spécifier un ou plusieurs chemins de feuilles de style :
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {}
Un nouveau builder "générique"
Angular a toujours disposé de différents builders pour construire nos applications. Il existe deux grands types d'applications Angular :
- Client-side rendering : l'application est entièrement construite côté client, c'est-à-dire que l'application est représentée sous forme de DOM (Document Object Model). La navigation, la récupération des données et le templating sont gérés côté client plutôt que côté serveur.
- Server-side rendering : l'application est générée en format HTML, chaque page étant rendue en HTML en réponse à une navigation, puis réhydratée pour devenir dynamique.
Selon ces deux types d'application, le builder utilisé était différent. Angular utilisait :
@angular-devkit/build-angular:browser
pour les applications client-side rendering,@nguniversal/builders:ssr-dev-server
pour les applications server-side rendering.
Avec l'introduction d'Angular 16, un nouveau builder expérimental a fait son apparition : @angular-devkit/build-angular:browser-esbuild
, permettant l'utilisation de Vite pour le dev-server et esbuild pour le build, offrant des performances exceptionnelles : une réduction de 87 % du temps de build de l'application et de 82 % pour le dev-server. Cependant, le builder pour le server-side rendering n'avait pas été modifié.
Avec l'arrivée d'Angular 17, un tout nouveau builder "générique" est introduit. Ce builder permet de construire à la fois des applications client-side et server-side rendering. Un tonnerre d'applaudissements pour le builder @angular-devkit/build-angular:application
!
Pour les applications existantes utilisant @angular-devkit/build-angular:browser-esbuild
, la migration vers le nouveau builder est relativement simple. Pour les applications server-side rendering, la migration est un peu plus complexe en raison du nombre de propriétés à modifier.
Un nouveau code flow
La sortie d'Angular 17 marque également l'introduction d'un nouveau flux de code, plus performant que son prédécesseur. Dans les versions antérieures, nous utilisions les directives structurelles telles que ngIf, ngSwitch, et ngFor pour gérer la structure de nos pages. Ces directives, puissantes grâce à leur microsyntaxe, ont toutefois leurs limites. D'où l'apparition de ce nouveau flux de code.
À quoi ressemble ce nouveau flux de code ? Prenons l'exemple suivant :
@Component({
standalone: true,
selector: 'app-root',
template: `
@if(name === 'SFEIR'){
<ul>
@for(entity of entities; track entity.id) {
<li>{{ entity.name }}</li>
}@empty {
No Data
}
</ul>
}@else {
Name not correct
}
`
})
export class AppComponent {
name = 'SFEIR';
entities = [{ name: 'Luxembourg', id: 'LU' }];
}
Comme le démontre ce code, il n'est plus nécessaire d'importer les directives ngIf et ngFor. Ce nouveau flux de code est intégré nativement dans Angular et facilitera l'intégration future des composants basés sur les signaux dans Angular. Bien que les directives structurelles ne soient pas obsolètes, il est possible que ngIf, ngFor et ngSwitch le deviennent à l'avenir. Pour migrer automatiquement vos composants vers ce nouveau flux de code, le schéma @angular/core:control-flow
sera d'une grande aide.
Attention : Ce nouveau flux de code étant très récent, des problèmes de formatage peuvent survenir. Notez que la version 3.1 de Prettier prend désormais en charge ce flux de code. Concernant les IDEs, VsCode, avec le plugin Angular Language Service, supporte déjà la coloration syntaxique de ce nouveau flux. Webstorm EAP gère également cette coloration, mais la vérification des templates reste à implémenter et sera disponible prochainement.
Defer, lazyloader facilement vos composants
C'est sûrement l'une des fonctionnalités les plus importantes de cette version : la capacité de charger paresseusement nos composants avec facilité.
Auparavant, nous avions la possibilité de le faire grâce aux EsModules et à la directive structurelle *ngComponentOutlet. Cependant, cette technique comportait des risques d'erreurs, le développeur devant gérer tout le processus de chargement (loading, error, etc.) et elle présentait des limitations (préchargement compliqué, par exemple). En somme, l'expérience développeur laissait à désirer.
Avec Angular 17, l'attribut @defer
vient simplifier le lazy loading en prenant en compte toutes les étapes du processus.
@Component({
selector: 'app-root',
template: `
<button type="button" #loadButton>Click Me</button>
@defer(on interaction(loadButton)) {
<app-lazy-component />
}@placeholder {
showed until the chunk file not begin to load
}@loading {
showed during the loading of the chunk
}@error {
showed if an error happen during loading
}
`
})
export class AppComponent {}
Il y a de nombreuses autres options pour @defer
, @placeholder
, et @loading
. Pour mieux maîtriser cette fonctionnalité, je vous recommande l'excellent article de Tomas Trajan ici.
Attention, comme pour toute bonne chose, il ne faut pas en abuser. L'application de @defer
dépendra de vos besoins spécifiques, principalement de votre réseau et de la taille du composant à charger paresseusement. Enfin, cette fonctionnalité sera précieuse pour optimiser les métriques LCP et CLS des Core Web Vitals.
Un petit mot sur signals
Signal était en phase de developer preview lors de la sortie d'Angular 16. Avec Angular 17, Signal est devenu stable et peut désormais être utilisé.
En le combinant avec l'option ChangeDetection.OnPush, vous obtiendrez une réactivité très précise, permettant de rafraîchir uniquement les composants affectés par les modifications des signaux.
Une petite migration est à prévoir : la méthode 'mutate' sur les signaux n'est plus disponible.
Quant aux "effects", ils restent pour l'instant en phase de developer preview.
Angular DevTools
Angular Devtools bénéficie également d'une nouvelle fonctionnalité très sympathique 😄 : il est désormais possible de visualiser l'arbre d'injection. Cela s'avère extrêmement utile pour déboguer une application confrontée à des dépendances circulaires ou lorsqu'un token n'est pas correctement résolu
Conclusion
Angular 17 apporte une multitude de nouveautés, ce qui justifie que l'on parle de renaissance pour ce framework. Comme pour les versions précédentes, Angular 17 n'introduit aucun changement majeur susceptible de perturber les applications existantes, rendant ainsi la migration d'Angular 16 vers Angular 17 relativement aisée.
Il est important de noter que l'utilisation de toutes ces nouvelles fonctionnalités n'est pas obligatoire ; elles sont mises à disposition des développeurs qui souhaitent les explorer.