AngularJS pour aujourd'hui et pour demain
Le mercredi 22 et le jeudi 23 octobre a eu lieu la conférence ngEurope à Paris. Cette conférence avait principalement pour but de lever le voile sur le futur du framework front end porté par Google : AngularJs. Un des objectifs principaux de ces deux jours était donc d’avoir une vision de ce à quoi va ressembler la version 2.0 du framework. Cependant, loin de vivre dans le songe d’un futur encore lointain (aucune date de release n’a encore été officialisée), ces deux jours ont aussi été l’occasion de découvrir un écosystème gravitant autour du framework très riche et surtout bien ancré dans le présent. On y a entendu des talks sur des sujets aussi variés que la sécurité, l’accessibilité, les bonnes pratiques de développement, le web mobile, le material design, les tests, les animations riches, les web components et bien d’autres encore. Qu'il s'agisse de la toute fraiche version 1.3 déjà sortie en version stable que du fonctionnement de la future version 2.0, cet article va se concentrer sur les nouveautés du framework annoncées pendant la conférence.
Keynote
Le premier jour a commencé par une keynote de Igor Minar et Brad Green qui nous présentent notamment quelques chiffres autour du framework. On y apprend que la communauté est très présente sur le framework puisqu’il y a plus de 1000 contributeurs sur le repository Github (contre ~ 400 pour emberjs et ~ 200 pour backbone), que le nombre de favoris ("star") est de plus de 30 000 pour AngularJs (contre ~11 000 pour emberjs et ~20 000 pour backbone) et que le nombre d’applications augmente de façon quasi exponentielle. Il s’agissait donc par cette introduction de montrer l’intérêt que suscite AngularJs et la dynamique de sa communauté.
Le reste de la keynote a été dédiée à introduire les différents concepts qui allait être abordés dans le reste de la conférence.
The "Superluminal Nudge” : AngularJs 1.3
On entre dans le coeur du sujet avec la présentation de la nouvelle version de AngularJs “Superluminal Nudge” (1.3) qui est tout juste sortie en version stable le 14 octobre.
Une appli qui booste
Il semblerait tout d'abord qu'il y a eu un gros travail réalisé sur un point critique lorsqu'il s'agit d'effectuer des traitements côté client : les performances. En effet, Jeff Cross et Brian Ford nous montrent les résultats plutôt impressionnants des tests de performance sur la boucle de $digest et sur la manipulation de DOM que voici :
On ajoutera que des améliorations significatives de performances sont encore possibles en désactivant (pour la production) les informations de debug :
$compileProvider.debugInfoEnabled(false);
Avec Angular on a le double data binding qui nous permet d'avoir une synchronisation en temps réel entre un model et le DOM. C'est ce système qui fait en partie la force d'Angular mais cela implique aussi qu'une vérification de modification du model à chaque boucle de $digest doit avoir lieu. Avec Angular 1.3 il est maintenant possible d'indiquer que l'on veut que le binding ne se fasse qu'une bonne fois pour toute afin de gagner en performance, c'est le "One Time Binding" (notez les '::').
<table> <tr ng-repeat="stock in ::myStocks"> <td ng-bind="::stock.symbol"></td> <td ng-bind="stock.currentQuote"></td> <td>Suggested Price: {{::calcValue(stock)}}</td> </tr> </table>
Une appli qui a la form
Au niveau fonctionnel, de gros efforts ont été faits sur la gestion des formulaires. On citera tout d'abord la possibilité de faire des validations de formulaire asynchrone (par exemple, rechercher dynamiquement la présence d'un login) :
ngModel.$asyncValidators.isUserAvailable = function(modelVal, viewVal) { var val = modelVal || viewVal; return $http.get('/api/isUsernameAvailable?username=' + val); }
De nouvelles options ont également été ajoutées à ngModel :
debounce (attendre un delay avant de synchroniser):
<input ng-model="data" ng-model-options="{debounce: 500}">
updateOn (attendre un évènement avant de synchroniser) :
<input ng-model="data "ng-model-options="{updateOn:'blur'}">
Pour finir avec les formulaires on notera la présence d'une nouvelle directive : ngMessage. Cette directive nous permet de nous débarrasser pour de bon des div avec ng-show et une condition contenant les erreurs sous cette forme : "signup.userEmail.$error.minlength". Maintenant pour afficher des messages d'erreurs on fera plutôt de cette manière plus lisible :
<ng-messages for="signup.userEmail.$error"> <ng-message when="required">You did not enter a field</ng-message> <ng-message when="email">Your field is not an email</ng-message> <ng-message when="minlength">Your field is too short</ng-message> </ng-messages>
En vrac
D'autre améliorations sont également de la partie pour cette version 1.3. On notera la présence d'une nouvelle dépendance "ng-aria" qui permet (si elle est importée) d'ajouter automatiquement des attributs aria-xxx aux balises html suivant l'état en cours. Par exemple, en presence d'un ng-show dans une balise, si la condition est fausse (et donc que les fils de cette balise deviennent invisibles) un attribut aria-hidden va s'ajouter automatiquement. Un nouveau watcher fait son apparition : le $watchGroup qui permet, comme son nom l'indique, d'écouter des modifications sur un panel d'objet:
$scope.$watchGroup(['user.email', 'user.name', 'user.phone'],updateUserOnServer);
Il est maintenant possible d'utiliser du SVG comme base de template d'un directive.
Angular 2.0
C'était probablement le moment le plus attendu de la conférence, l'annonce du fonctionnement de Angular 2.0. Mais avant d'entrer dans les concepts clés de la nouvelle mouture du framework intéressons nous d'abord au nouvel environnement Javascript dans lequel va évoluer le framework
Ecma Script 6, TypeScript, AtScript et Traceur
La version actuelle de AngularJs est construite grace à Javascript et plus particulièrement à l'implémentation du standard EcmaScript 5 qui est aujourd'hui le standard compris par tous les navigateurs. Mais une nouvelle version de ce standard est actuellement en cours de validation. Il s'agit de... EcmaScript 6 ! Cette nouvelle version du standard ajoute notamment la notion de "class" et de "module" nativement à javascript. AngularJS 2.0 sera donc basé sur ES6 mais ce n'est pas tout !
Microsoft a créé sa propre extension de langage à ES6. Il s'agit de TypeScript. TypeScript se place au dessus de ES6 et ajoute la notion de typage statique à ES6. Les fichiers contenant du TypeScript sont compilés pour rendre du ES6 ou ES5 traditionnel.
Mais pour Google, ce n'étais encore pas suffisant et ils ont décidé de créer leur propre extension de langage qui reprend les idées de TypeScript en en ajoutant de nouvelles. Il s'agit de AtScript. AtScript ajoute au standard l'introspection de type, et les annotations. On ajoutera que contrairement à TypeScript, AtScript propose un système de typage dynamique.
AngularJS 2.0 sera donc basé sur AtScript. Cependant la compatibilité avec ES5 est toujours possible grâce au compilateur Traceur qui permet de transformer du AtScript en ES6 et / ou en ES5.
Quoi de neuf du coté d'Angular 2.0 ?
Le clou du spectacle a eu lieu au début de la seconde journée de ngEurope. La présentation que tout le monde attendait avec impatience n'a pas laissée indifférente. Intitulée sobrement "AngularJS 2.0 Core" cette présentation d'Igor Minar et Tobias Bosch nous en a appris beaucoup sur le futur d'AngularJS.
On commence par la nouvelle syntaxe utilisée dans les templates html. Ci-dessous un exemple "avant / "après" :
Angular 1.3 <div ng-controller="SantaTodoController"> <input type="text" ng-model="newTodoTitle"> <button ng-click="addTodo()">+</button> <tab-container> <tab-pane title="Tobias"> <div ng-repeat="todo in todosOf('tobias')"> <input type="checkbox" ng-model="todo.done"> {{todo.title}} <button ng-click="deleteTodo(todo)">X</button> </div> </tab-pane> ...
Angular 2.0 <div> <input type="text" [value]="newTodoTitle"> <button (click)="addTodo()">+</buton> <tab-container> <tab-pane title="Good kids"> <div [ng-repeat|todo]="todosOf('good')"> <input type="checkbox" [checked]="todo.done"> {{todo.title}} <button (click)="deleteTodo(todo)"> X </button> </div> </tab-pane> ...
Dans cet exemple on remarque plusieurs changements. Avec Angular 2.0 on oublie les "ng-click", "ng-keyup"... Les évènements sont maintenant écoutés grâce à une syntaxe générique qui est : "(eventName)". Cette syntaxe permet de ne pas avoir un "ng-xxx" pour chaque évènement mais d'avoir une syntaxe qui fonctionne pour tous les évènements existants. Dans le même ordre d'idée, les attributs ont une syntaxe générique : "[attributeName]". Un des gros avantage de cette syntaxe générique est d'assurer l'interopérabilité avec les web components. En effet l'API de base des web components est d'envoyer des évènements et d'exposer des attributs.
Vous l'avez peut être remarqué : il n'y a plus de "ng-controller". Il s'agit d'un autre changement majeur en Angular 2.0. En effet, la nouvelle philosophie d'Angular est de n'utiliser que des directives. Il existera trois types de directives: les "Decorators Directives" utilisées par exemple pour remplacer les "ng-class", "ng-show", les "Templates Directives" utilisées notamment pour les "ng-repeat", "ng-if" et enfin les "Components Directives" qui correspondent aux directives que l'on a l'habitude de réaliser en Angular 1.x. Ce changement s'accompagne d'une nouvelle façon d'écrire les directives et qui utilise intensément les possibilités de EcmaScript 6 et TypeScript (class, annotations, types):
Nouvelle syntaxe pour les directives @ComponentDirective class SantaTodoApp { constructor() { this.newTodoTitle = ''; } addTodo: function() { ... } removeTodo: function(todo) { ... } todosOf: function(filter) { ... } }
Cette décomposition en directives signe également la mort du très célèbre $scope. En effet, avec Angular 2.0 le contexte d'execution est maintenant la directive et plus le controller, les appels à des variables ou des fonctions depuis le template seront donc directement liés au composant dans lequel ils s'exécutent. L'injection de dépendance se fera désormais depuis le controller des directives (ou service) et permettra par exemple à deux composants de pouvoir communiquer entre eux.
Une autre grande nouveauté de Angular 2.0 est la refonte du système de routing. L'équipe derrière Angular a bien compris les limitations du routeur actuel (basé sur le principe une URL / une vue / un controller) et a décidé de recréer un nouveau routeur. Pour cela il s'inspire grandement du composant open source "ui-router" bien plus complet car il est basé sur un principe d'état qui permet par exemple de faire des routes imbriquées. Le nouveau routeur permettra, en vrac, de gérer plusieurs routing en parallèle (pour gérer des transitions de façon modulaire dans l'application) ou encore d'effectuer des actions pendant l'activation ou la désactivation d'écran. Pour ceux qui sont impatients de pouvoir l'utiliser, rassurez vous, vous n'aurez pas à attendre la version 2.0 pour vous en servir car l'équipe derrière Angular compte le porter pour la version 1.3.
De grandes modifications structurelles ont donc été réalisées. Une grande majorité des notions dont on a l'habitude sur Angular 1 va tout bonnement disparaitre dans la version 2. On peut également citer la disparition de l'utilisation de JqLite (le sous ensemble de Jquery permettant de manipuler le DOM) pour une manipulation directe du DOM ou encore la disparition du système de module made in Angular remplacé par l'import de module EcmaScript 6. La dernière slide de la présentation résume bien les différentes modifications apportées au framework :
Mais aujourd'hui on fait quoi ?
La version 2.0 du framework est encore en phase développement intensif par les équipes de Google. Il n'y a de plus aucune date de release annoncée, tout au plus une estimation qui varie entre fin 2015 et début 2016. Pas la peine donc de se précipiter pour faire ses projets en Angular 2.0 (même s'il est toujours intéressant de rester informé sur son évolution) d'autant plus que beaucoup d'eau va encore couler sous les ponts et ce qui a été annoncé à ngEurope ne sera peut être plus totalement vrai d'ici la sortie officielle.
Aujourd'hui il convient donc de continuer à developper ses applications Angular en version 1.x. Google a assuré qu'il continuera à faire évoluer et à maintenir la branche 1.x jusqu'a un à deux ans après la sortie de la version 2.0. Cela ne veut pas dire que les applications créées à partir d'une version 1.x ne fonctionneront plus ou ne pourront plus évoluer mais que le langage n'évoluera plus. Bien qu'il semble peu probable que le portage d'une application 1.x en 2.0 soit faisable, Google annonce tout de même qu'après la sortie de la version 2.0 il proposeront une manière de migrer les applications faites en 1.x.
Suggestion d'articles :
- Paris web 2014 : les T.I.C et l'éthique
- Retour d’expérience : 5 idées pour améliorer les performances d’une application Web AngularJS
- Les nouvelles architectures front Web et leur impact sur les DSI – Partie 1
- Les nouvelles architectures front Web et leur impact sur la DSI – partie 2
- Développer un jeu avec JHipster, HTML 5 et LeapMotion
Les images et exemples de codes ont été extraits des slides des différentes sessions disponibles ici :