Web Components : l’adoption pourrait s’accélérer !

 

Le sujet n’est pas nouveau, on parle des Web Components depuis 3 ans environ. En 2015, j’ai eu à développer pour l’un de nos clients 2 composants (Polymer 1.0), à intégrer dans un premier temps dans une application hôte écrite en AngularJS. Ces composants seront repris plus largement au sein de l’entreprise dans un second temps.

Deux ans plus tard, alors que j’assiste à la deuxième session du Google Developer Festival Toulousain, la présentation d’Horacio Gonzalez et Cyril Balit intitulée « Mixité dans le monde des Web Components » m’interpelle : où en est-on dans ce domaine ? Les difficultés d’intégration que j’avais rencontrées avec AngularJS ont-elles été partagées par d’autres développeurs et sont-elles toujours d’actualité ?

Petit rappel

Derrière ce que l’on appelle couramment Web Component, il y a en fait quatre normes du W3C désormais intégrées aux navigateurs modernes :

  • Custom Elements : c’est la possibilité de faire connaître au navigateur un élément HTML “custom”, càd non standard. Exemple :<google-map latitude=”” longitude=””/>$
  • Shadow DOM : le composant possède son propre arbre DOM, isolé du DOM de l’application hôte, ce qui évite les interférences CSS avec celle-ci
  • HTML Imports : capacité à importer un composant externe <link rel=”import” href=”http://…/mycomponent.html”>
  • HTML Template : définition du “design”, du corps du composant, par un template HTML

Tous les navigateurs n’en sont pas au même niveau de compatibilité avec ces différentes normes. Heureusement, en utilisant le Polyfill de webcomponents.org, ce manque est facilement comblé. Expérience à l’appui, les composants que nous avons développés fonctionnent avec IE10 et plus.

A noter que dans un avenir proche, les imports ne devraient plus se faire via la norme HTML Imports mais via la gestion des modules proposée par ES6.

En résumé, un Web Component peut être vu comme une brique réutilisable (boîte noire) que l’on manipule via les éléments suivant :

  • attributes : attributs HTML permettant de passer des informations en entrée ❶
  • properties : propriétés (read/write) de l’objet pour le manipuler programmatiquement ❷
  • methods : déclencher des actions sur le composant ❸
  • events : écouter les évènements levés par le composant ❹
<custom-searchkeyword="hello" ❶></custom-search>
// get the component custom-search
var customSearch = document.querySelector('custom-search') ;
// method call, ex : launch search with the given keyword
customSearch.launchSearch(keyword) ; ❸
// listen to component events
customSearch.addEventListener('response-received', doSomething) ; ❹
// read property 'results' that contains displayed items
var results = customSearch.results ; ❷

 

Pourquoi faire des Web Components ?

A priori, la question paraît illégitime: on a ici quelque chose de normé, largement supporté par les navigateurs du marché, et réutilisable. Tout développeur sensé devrait donc déjà être passé par les Web Components. Pourtant nous ne le faisons pas, car nous utilisons déjà tous un framework qui offre sa propre manière de faire des composants : AngularJS, Angular, React, VueJS, etc.

Utiliser un framework d’une part et des Web Components d’autres part, c’est maîtriser deux technologies au lieu d’une et aussi rencontrer des difficultés à les faire interagir. Afin de nous convaincre du bien fondé des Web Components, Horacio et Cyril ont mené l’exercice…

Intégration des Web Components dans les frameworks du moment

Afin d’être exhaustive, l’évaluation a été faite de la manière suivante : 3 composants de nature différentes ont été intégrés dans 4 applications hôtes.

Composants :

  • un composant écrit de manière native : en pur javascript
  • un composant plus complexe : écrit avec Polymer
  • un composant fourni par google : <google-map />

Les 3 composants ont été testés dans une même application réécrite 4 fois avec :

  • AngularJS
  • Angular (2)
  • React
  • VueJS

De manière générale, les choses se passent à peu près bien dans les 4 cas, moyennant quelques manipulations. Les difficultés que l’on va rencontrer vont tourner autour :

  • Custom Element : reconnaissance du composant par le framework
  • Data Binding : transmission des informations via les attributs HTML du composant
  • Events : catch des évènements émis par le composant

 

AngularJS Angular 2 React VueJS
Custom Element      √
Data Binding    √  
Events  √  

 

❶ Côté AngularJS : le Data Binding fonctionne bien, le composant Polymer reçoit bien les données et il est aussi en mesure de catcher les changements de valeur de l’application hôte. Cependant, lorsqu’il s’agit de passer un boolean, permettant par exemple de masquer ou afficher une zone, un composant utilisé de la manière suivante fonctionnera mal :

<element open="{{person===currentPerson}}">

En effet, l’expression évaluée peut renvoyer la chaîne de caractère “false”qui s’évalue en javascript à … true.
❷ AngularJS propose sa propre gestion des évènements, qui n’est pas celle native aux navigateurs et n’est donc pas compatible avec les Web Components. En AngularJS, pour catcher l’évènement click, on utilise ng-click et non pas onclick, ni addEventListener(“click”).

❸ En Angular 2, toute balise HTML de la forme <xxx-yyy /> est considérée comme un composant Angular, ce qui va pousser le framework à rechercher un composant connu parmi les composants Angular enregistrés. Pour pallier ce problème, le module Angular doit être configuré de la sorte :

@NgModule({
   schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
})

 

❹ React : le composant s’intègre parfaitement dans la syntaxe JSX. Cependant, React ne reconnaît qu’une « liste blanche » d’évènements. Le problème a été résolu en utilisant une librairie complémentaire react-polymer. Une alternative est aussi d’écouter l’évènement de manière programmatique (méthode addEventListener).

Comme on peut le constater, les difficultés sont plus nombreuses côté AngularJS, alors que l’intégration est bien meilleure sur les frameworks les plus récents (notamment VueJS). Ceci n’est pas étonnant car ces derniers ont été créés en tenant compte de l’arrivée des Web Components.

J’ai été quelque peu rassuré de constater que les speakers ont rencontré les mêmes problèmes que moi concernant AngularJS et que la solution proposée a été la même : encapsuler (wrapper) le composant dans une directive AngularJS.

Et donc, pourquoi faire des Web Components ?

Nous connaissons tous la (courte) durée de vie des frameworks javascript. Pour tous ceux qui migrent en ce moment même de AngularJS à Angular 2 (ou plutôt 4), tous les composants sont à réécrire. En produisant des composants indépendants du framework hôte, nos développements gagneraient à être plus pérennes :

  • le travail pourrait être partagé entre les équipes (avec des technos différentes)
  • les composants peuvent être réutilisés et donc valorisés auprès de nos clients, car exportable
  • les migrations de frameworks (ou les montées en version) seraient moins coûteuses

A noter que si l’adoption des Web Components semble progresser lentement, des acteurs bien connus comme Ionic pourraient aider à faire bouger les choses. En effet, après avoir écrit leurs composants en AngularJS puis les avoir porté en Angular récemment, l’équipe Ionic participe désormais au projet Stencil. Il s’agit d’un compilateur (basé sur TypeScript et JSX) permettant de générer des Web Components natifs.

L’équipe a déjà annoncé au dernier Polymer Summit que la prochaine version de leurs composants sera disponible sous forme de Web Components.

 

Share
Guillaume PARAMELLE
Guillaume PARAMELLE

332

Leave a Reply

Your email address will not be published. Required fields are marked *