- Les composants web peuvent sembler être la version navigateur des composants React, mais en réalité ils se rapprochent davantage d’un modèle qui place le HTML existant au centre et y ajoute des fonctionnalités
- La différence clé réside dans le rendu avant l’exécution de JavaScript : plutôt que de passer des données à un élément personnalisé vide, il est plus naturel d’envelopper du HTML porteur de sens dans un élément personnalisé
- Un HTML web component étend le balisage existant, tandis qu’un élément vide dont le contenu et les fonctionnalités reposent entièrement sur JavaScript se rapproche davantage d’un composant web JavaScript
- Si l’approche de composition façon React est familière avec l’idée de remplacement, les composants web demandent une logique d’augmentation : ajouter des fonctionnalités tout en conservant le contenu
- Sur la plateforme web, comme avec HTML5,
fetch ou certaines évolutions liées à TypeScript, les bonnes idées ont tendance à survivre longtemps en renforçant les technologies existantes plutôt qu’en les évincant
Les composants web et les composants React n’ont pas la même logique
- Le nom « web components » peut donner l’impression qu’il s’agit de l’équivalent, sur la plateforme web, des composants React
- Le JSX de React utilise la forme
<MyComponent>, tandis que les composants web peuvent utiliser la forme <my-component>
- Mais si l’on crée des composants web comme on crée des composants React, on risque vite d’être frustré
- Les deux technologies diffèrent par les capacités qu’elles privilégient et leur mode d’utilisation
- Vouloir utiliser l’une comme l’autre va à l’encontre de la direction naturelle de chaque technologie
Les composants web HTML sont mieux adaptés à l’augmentation qu’au remplacement
- Un composant React classique peut prendre la forme d’un composant vide auquel on passe des données via des propriétés, JavaScript se chargeant de rendre l’ensemble du contenu
<UserAvatar
src="https://example.com/path/to/img.jpg"
alt="..."
/>
- À première vue, un composant web peut être écrit de la même manière
<user-avatar
src="https://example.com/path/to/img.jpg"
alt="..."
></user-avatar>
- Mais la force propre des composants web est qu’ils permettent un rendu avant JavaScript
- Les composants React ne peuvent pas fonctionner de cette manière
- C’est pourquoi, plutôt qu’un « composant coquille » vide, il est souvent plus pertinent de construire le contenu principal en HTML puis de l’envelopper dans un élément personnalisé qui y ajoute des fonctionnalités
<user-avatar>
<img src="https://example.com/path/to/img.jpg" alt="..." />
</user-avatar>
- La distinction proposée par Jeremy dans « HTML web components » se concentre sur le fait qu’un élément personnalisé étende ou non un balisage existant
- Si l’élément personnalisé est vide, ce n’est pas un composant web HTML
- S’il enveloppe un balisage existant pour l’étendre, il se rapproche d’un composant web HTML
- Un « JavaScript web component » désigne une forme où le contenu et les fonctionnalités d’un élément vide dépendent entièrement de JavaScript
<user-avatar
src="https://example.com/path/to/img.jpg"
alt="..."
></user-avatar>
- Sous cette forme, sans JavaScript, cela n’a aucun sens pour l’utilisateur final
- À l’inverse, un composant web HTML conserve du sens et du contenu même sans JavaScript, et lorsque JavaScript est présent, il vient y ajouter des fonctionnalités
<user-avatar>
<img src="https://example.com/path/to/img.jpg" alt="..." />
</user-avatar>
Sur le web, l’approche par augmentation dure dans le temps
- Si l’approche augmentative fonctionne bien sur le web, c’est parce que la nature du web encourage un renforcement progressif résilient et qu’elle convient bien à la transformation répétée d’un ensemble aussi vaste que le web
- Les bonnes idées issues des frameworks et bibliothèques autour du web, même lorsqu’elles sont absorbées par la plateforme, y entrent souvent sous une forme qui renforce l’existant au lieu de le remplacer entièrement
- XHTML a tenté de remplacer HTML4, tandis que HTML5 a cherché à renforcer HTML4, et c’est HTML5 qui l’a emporté
- Des bibliothèques de réseau ont essayé de remplacer
XMLHttpRequest, et leurs bonnes idées ont fini par être intégrées dans le standard fetch
fetch existe aujourd’hui aussi dans de nombreux environnements hors navigateur
- Les bonnes idées de Sass et de jQuery ont également été reprises par les navigateurs
- Les bonnes idées de TypeScript arrivent elles aussi dans les navigateurs en renforçant les technologies existantes plutôt qu’en les remplaçant
- On peut voir les composants web comme une évolution où le modèle de composant de React arrive dans le navigateur, mais davantage sous une forme qui renforce le fonctionnement déjà en place du web qu’une forme qui le remplace
- Si l’on recherche une approche technique durable, mieux vaut choisir l’augmentation et l’amélioration plutôt que le remplacement, car c’est plus conforme à la direction prise par le web
1 commentaires
Avis de Hacker News
J’espérais que cet article expliquerait ce que
user-avatarfait ou fournit réellement, mais ce n’est jamais venuS’il ne contient que du style, je ne vois pas pourquoi on n’utiliserait pas simplement une classe CSS, et il semblerait bien plus naturel que
user-avataraccepte un attributsrcplutôt que d’obliger à y mettre une baliseimgà chaque foisVue/React/Angular ne cherchent pas tant à « remplacer » HTML qu’à s’empiler au-dessus de HTML/CSS/JS ; si tout était rendu dans un canvas, cet argument m’aurait paru plus convaincant
J’avais de l’espoir pour les Web Components lorsqu’ils ont été annoncés, mais leurs fonctionnalités fournies par défaut sont trop limitées, et ils donnent peu l’impression d’aider concrètement à créer des applications web comme le font les frameworks
Les alternatives aux gros frameworks, en particulier des choses comme htmlx, ressemblent à une variante de jQuery avec un peu de sucre syntaxique, ce qui semble être un net retour en arrière pour construire des applications web
Si par « application web » on entend quelque chose comme Google Sheets, je suis d’accord, mais ce courant anti-React semble plutôt critiquer l’habitude de partir d’un framework par défaut et de tout construire dessus dès le départ
Il existe beaucoup de sites web qui n’ont en réalité besoin que d’« une légère couche d’interaction » par-dessus
Le principal avantage est l’amélioration progressive : comme une balise
imga un comportement par défaut, on peut s’appuyer sur le rendu de base et ne « renforcer » avec des composants web que les parties nécessairesLe composant
details-utilsrenforce le comportement du composant HTML intégrédetailSi JavaScript est désactivé pour une raison quelconque, le composant
detailfonctionne toujours comme prévu ; si JavaScript est activé ou une fois le téléchargement terminé, il bénéficie de comportements améliorés, comme se replier lors d’un clic à l’extérieurDans cette approche, la partie réutilisable est précisément ce renforcement du comportement
C’est en voyant ce composant web du créateur de 11ty que j’ai compris le propos de l’article, et le point qui m’avait frappé en découvrant les Web Components — « au final, il faut quand même JavaScript, et sans lui ça ne marche pas » — apparaît aussi dans l’article de Rich Harris : https://dev.to/richharris/why-i-don-t-use-web-components-2ci...
htmx consiste surtout à étendre le paradigme du HTML rendu côté serveur en évitant d’écrire du JavaScript, avec des mises à jour partielles de page plutôt que des rechargements complets
Pour en voir davantage sur l’idée des « HTML Web Components », ces articles valent aussi la peine d’être lus
https://meyerweb.com/eric/thoughts/2023/11/01/blinded-by-the... - « So there you have it: a few thousand words on my journey through coming to understand and work with these fully-Light-DOM web components, otherwise known as custom elements. Now all they need is a catchy name, so we can draw more people to the Light Side of the Web. »
https://adactio.com/journal/20618 propose un nom qui tient la route
C’est pénible à écrire, si bien qu’on finit par avoir besoin d’un framework léger au-dessus d’un framework intégré comme Lit, et Lit est même plus gros que Preact
En plus, il ne résout pas de vrais problèmes comme la gestion d’état ou le routage, donc il faudra très probablement ajouter encore d’autres choses
On peut obtenir des composants réutilisables, mais si l’on se demande si, dans un projet utilisant React, on va intégrer un composant web qui utilise Vue en interne, cela ne tient pas vraiment debout
La beauté et l’élégance du Web venaient de sa structure déclarative, qui rendait possibles l’observabilité et la modification
Le Shadow DOM m’a toujours semblé répondre à un désir très corporate d’ériger des barrières d’encapsulation plus hautes et d’obtenir davantage de certitude, ce qui n’était pas un objectif que je partageais personnellement
Cet article montre comment le travail avec le Light DOM peut se composer
J’ai toujours pensé que les composants web ou éléments personnalisés devaient pouvoir modifier eux-mêmes le DOM interne, déplacer leurs enfants et créer du nouveau contenu
Par exemple, une page ou un framework peut insérer une icône, et un élément d’avatar utilisateur peut insérer un nom ou des éléments décoratifs
Cela dit, une inquiétude que j’ai avec le Light DOM/les HTML Web Components est que le Shadow DOM apporte certains avantages en matière de performances
En tant que développeur, je visualise bien le fait qu’il puisse réduire le nombre d’éléments que les sélecteurs CSS doivent parcourir, et j’aimerais pouvoir profiter de cet avantage d’une manière ou d’une autre
Je suis vraiment content de voir une approche plus légère des éléments personnalisés et des Web Components, et merci pour les liens
L’affirmation « on peut effectuer le rendu avant JavaScript. Les composants React ne pourront jamais faire ça » est difficile à soutenir de façon catégorique : avec le rendu côté serveur, le rendu peut avoir lieu avant le JavaScript côté client.
Je trouve que l’exemple est trop simple pour illustrer l’argument de l’auteur.
Un composant web qui gère des changements d’état aurait été un meilleur point de comparaison, et l’argumentation aurait sans doute été plus solide.
Il existe des solutions d’hydratation, mais elles sont généralement pires, avec des compromis surprenants, et nuisent souvent à la composabilité.
Avec le seul exemple qui encapsule une balise
img, l’intérêt ne m’a pas vraiment sauté aux yeux ; on peut certes regrouper et réutiliser des éléments communs, mais dès qu’il faut de l’interaction, JavaScript reste nécessaire.Même le texte alternatif de l’image dans l’exemple est aujourd’hui généralement dynamique à cause de la localisation, donc sans JavaScript, une partie du contenu peut manquer.
J’ai l’impression d’avoir enfin compris l’intérêt des Web Components : https://github.com/kennyfrc/cami.js
“No Build Steps, No Client-Side Router, No JSX, No Shadow DOM. We want you to build an MPA, with mainly HTML/CSS, and return HTML responses instead of JSON. Then add interactivity as needed.”
“Declarative templates with lit-html. Supports event handling, attribute binding, composability, caching, and expressions.”
Personnellement, j’aime bien les classes dans le style des composants de classe React, avec une machine à états intégrée inspirée de XState.
https://github.com/codewithkyle/supercomponent/blob/master/s...
L’orientation semble assez similaire, et la communauté de HTMX est peut-être plus grande.
Si tu l’as essayé, je serais curieux de savoir ce qui t’a semblé manquer.
Les « web components » ne sont pas une seule chose, et on ne crée pas non plus « a web component ».
« Web Components » est le nom de la Web Components API, qui regroupe trois choses.
Ce que l’on crée réellement, ce sont des éléments personnalisés ; on peut y utiliser Shadow DOM, ou des templates HTML.
Parmi les trois, le plus important est l’élément personnalisé.
L’idée centrale étant « créer davantage d’éléments HTML », c’est à vous de décider quels attributs et quelles API JavaScript ils prennent en charge.
La façon de les placer sur une page, d’interagir avec eux et d’écouter leurs événements est identique à celle des autres éléments HTML.
Si vous savez écrire des pages web « à l’ancienne », vous savez déjà utiliser des éléments personnalisés ; il ne vous reste qu’à apprendre à les déclarer.
J’ai récemment commencé à expérimenter les Web Components sans environnement de build.
Pas de npm, bun, webpack ou autre, aucune dépendance, et le code est écrit en TypeScript.
IntelliJ compile automatiquement en JavaScript, et la vue navigateur injecte un petit gestionnaire de détection des changements pour les mises à jour en temps réel pendant le développement.
Jusqu’ici, je n’ai pas eu de problème.
Ce qui semble freiner les Web Components, ce sont les HTML Modules.
Ce serait bien de pouvoir lier un fichier
.html, plutôt qu’un fichier.js, pour importer un composant web, mais aujourd’hui, si l’on veut utiliser des templates ou quelque chose d’un peu plus complexe, il faut faire une injection assez laide du genre.innerHtml = \...``.Je pensais que ce serait problématique, mais l’IDE analyse plutôt bien les chaînes de templates.
Et ce n’est pas non plus la seule raison qui freine les Web Components.
J’ai du mal à adhérer à l’idée que « React remplace au lieu d’améliorer »
Au bout du compte, React rend lui aussi des éléments HTML et y attache des gestionnaires d’événements JavaScript
Envelopper
imgdans un composant React ne lui retire pas ses fonctionnalités : on ajoute quelque chose par-dessus, autrement dit on l’amélioreL’auteur a peut-être travaillé sur d’autres bases de code React, mais d’après mon expérience, quand nous n’avons pas de raison de faire autrement, nous utilisons telles quelles les fonctionnalités intégrées du navigateur
Peut-être ai-je simplement eu de la chance
Le point essentiel est que l’approche des « HTML Web Components », contrairement à React, ne dépend pas de JavaScript pour commencer le rendu
Du point de vue du rendu par le navigateur, React correspond à « chargement de la page → chargement du composant », tandis que les Web Components sont plus proches de « chargement de la page → rendu de base → chargement du composant »
Une personne qui désactive JavaScript peut quand même voir quelque chose avec un web component, alors qu’elle peut ne rien voir du tout avec React ; et avec JavaScript, on peut passer à un état de rendu plus avancé
Par exemple, si l’on assigne
onchangeà un élément, React ne fournit pas vraiment un événementchange, mais quelque chose de plus proche d’un événementinputEn réalité, ce n’est ni l’un ni l’autre : il fournit un événement synthétique plus proche de
inputque dechangeSi l’on veut réellement
change, il faut utiliser une référence vers l’élément et attacher directement le gestionnaire dans un effetSi l’on renvoie du HTML depuis le serveur avec React, envelopper
imgdans un composant React revient bien à améliorer l’élément existantMais si tout est rendu côté client, cet
imgne peut finalement pas être dissocié du composant ReactD’après mon expérience, React est excellent quand on lui confie toute la structure de la page de haut en bas, mais cela peut devenir difficile lorsqu’on essaie de l’insérer dans une structure existante, par exemple avec du rendu côté serveur
Si l’on cherche une approche durable, la conclusion selon laquelle il faut choisir l’amélioration progressive plutôt que le remplacement correspond aussi à mon expérience
Grâce à cette philosophie, mes projets web ont duré longtemps avec un minimum de maintenance et de dépendances
Un web component doit faire une seule chose, tandis qu’un framework JavaScript se rapproche d’un écosystème complet
J’ai créé un web component de lecteur vidéo capable d’accepter plusieurs entrées, la plus complexe étant un fichier torrent
Avec StencilJS [0], j’aurais pu le porter vers Vue/React, mais il était déjà parfaitement utilisable sans cela
Il suffit d’insérer la balise correspondante avec la classe exportée depuis
awesomePlayer.jspour obtenir un lecteur vidéo HTML5 prêt à copier-coller, capable de lire des torrentsJe recommande aussi fortement, quand c’est possible, d’imiter les éléments HTML existants
Par exemple, j’ai utilisé
srcparce quevideofonctionne ainsi ; cela permet aux utilisateurs d’interagir avec le composant sans devoir fouiller la documentation[0] https://stenciljs.com/
J’ai du mal à être d’accord avec l’idée que les composants des frameworks front-end seraient entièrement des remplacements et ne seraient pas composables
En surface, cela peut sembler vrai, mais dans mes composants j’utilise beaucoup les slots, et leur implémentation est simple tout en se comportant naturellement
À l’inverse, les Web Components sont généralement démontrés en injectant énormément de code pour construire quelque chose comme un éditeur
Utiliser des slots dans les Web Components est pénible : il faut attacher beaucoup de nœuds manuellement, manipuler les templates sous forme de chaînes, et, dès que l’on veut faire quelque chose d’un peu complexe, écouter aussi l’événement
slotchangeEn substance, cela revient à utiliser l’API DOM ; et si cette API n’était pas aussi affreuse, on ne serait probablement jamais passé à des frameworks front-end comme React
Je ne suis pas non plus d’accord avec l’argument annexe selon lequel XHTML a échoué parce qu’il n’améliorait pas HTML
À mon avis, il a échoué parce que les applications devaient être entièrement valides et que cette validation était confiée au client/navigateur
Si l’on utilisait du vrai XHTML, la moindre petite erreur de balisage aurait cassé la page ; tout le monde validait donc XHTML par souci de compatibilité future, mais aucune entreprise n’aurait pris le risque de voir son activité tomber en panne simplement parce qu’une balise
pn’était pas correctement fermée