Fermer

juillet 16, 2018

Éléments personnalisés, DOM Shadow et NPM


À propos de l'auteur

Oliver Williams est un développeur front-end à Springer Nature .
En savoir plus sur Oliver

Cet article se penche sur l'enrichissement du langage HTML avec des composants qui ont des fonctionnalités et des styles intégrés. Nous apprendrons également comment rendre ces éléments personnalisés réutilisables dans des projets utilisant NPM.

Même pour les composants les plus simples, le coût du travail humain peut avoir été important. Les équipes UX effectuent des tests d'utilisabilité. Un certain nombre de parties prenantes doivent signer la conception.

Les développeurs effectuent des tests AB, des audits d'accessibilité, des tests unitaires et des contrôles croisés par navigateur. Une fois que vous avez résolu un problème, vous ne voulez pas répéter cet effort . En construisant une bibliothèque de composants réutilisables (plutôt que de tout construire à partir de rien), nous pouvons continuellement utiliser les efforts passés et éviter de revisiter les problèmes de conception et de développement déjà résolus.


 Une capture d'écran du site Web des composants matériels de Google. preview </a><br />
 </figcaption></figure>
<p> Construire un arsenal de composants est particulièrement utile pour les entreprises comme Google qui possèdent un portefeuille considérable de sites Web partageant tous une marque commune. En codifiant leur interface utilisateur en widgets composables, les grandes entreprises peuvent à la fois accélérer le temps de développement et assurer la cohérence entre la conception visuelle et la conception de l'interaction utilisateur sur l'ensemble des projets. Les guides de style et les bibliothèques de modèles ont suscité un intérêt croissant au cours des dernières années. Étant donné que plusieurs développeurs et concepteurs se répartissent sur plusieurs équipes, les grandes entreprises cherchent à atteindre la cohérence. Nous pouvons faire mieux que de simples échantillons de couleurs. <strong> Ce dont nous avons besoin, c'est d'un code facilement distribuable </strong>. </p>
<h4> Code de partage et de réutilisation </h4>
<p> Le code de copier-coller manuellement est sans effort. Garder ce code à jour, cependant, est un cauchemar de maintenance. De nombreux développeurs s'appuient donc sur un gestionnaire de paquets pour réutiliser le code entre projets. Malgré son nom, le gestionnaire de paquets de nœuds est devenu la plate-forme inégalée pour la gestion des paquets frontaux <em> </em>. Il y a actuellement plus de 700 000 paquets dans le registre NPM et <em> des milliards </em> de paquets sont téléchargés chaque mois. Tout dossier contenant un fichier package.json peut être téléchargé sur NPM en tant que package partageable. Alors que NPM est principalement associé à JavaScript, un package peut inclure du code CSS et du balisage. Le NPM le rend facile à réutiliser et, surtout, <em> met à jour le code </em>. Plutôt que de devoir modifier le code dans une myriade d'endroits, vous ne modifiez le code que dans le paquet. </p>
<aside class=

Le problème de balisage

Sass et Javascript sont facilement portables avec l'utilisation des instructions d'importation. Les langages de modèle donnent au HTML la même capacité – les modèles peuvent importer d'autres fragments de HTML sous la forme de partiels. Vous pouvez écrire le balisage de votre pied de page, par exemple, une seule fois, puis l'inclure dans d'autres modèles. Dire qu'il existe une multiplicité de langues modèles serait un euphémisme. Vous attacher à un seul limite sérieusement la réutilisabilité potentielle de votre code. L'alternative est de copier et coller le balisage et d'utiliser NPM uniquement pour les styles et javascript.

C'est l'approche adoptée par le Financial Times avec sa bibliothèque de composants Origami . Dans sa conversation " ne pouvez-vous pas le faire plus comme Bootstrap?" 19458-004 "Alice Bartlett a conclu" il n'y a pas de bonne façon de laisser les gens inclure des modèles dans leurs projets ". Parlant de son expérience de maintenance d'une bibliothèque de composants chez Lonely Planet, Ian Feather a réitéré les problèmes de cette approche:

"Une fois qu'ils copient ce code, ils découpent une version qui doit être maintenue indéfiniment. Quand ils ont copié le balisage pour un composant de travail, il avait un lien implicite avec un instantané du CSS à ce moment-là. Si vous mettez ensuite à jour le modèle ou refactorisez le CSS, vous devez mettre à jour toutes les versions du modèle dispersées autour de votre site. "

Une solution: Web Components

Les composants Web résolvent ce problème en définissant le balisage en JavaScript. L'auteur d'un composant est libre de modifier le balisage, CSS et Javascript. Le consommateur du composant peut bénéficier de ces mises à niveau sans avoir besoin de naviguer à travers un projet modifiant le code à la main. Synchronisation avec les derniers changements à l'échelle du projet peut être réalisé avec une mise à jour npm laconique via le terminal. Seul le nom du composant et son API doivent rester cohérents.

L'installation d'un composant Web est aussi simple que de taper npm install component-name dans un terminal. Le Javascript peut être inclus avec une instruction import:

 

Vous pouvez ensuite utiliser le composant n'importe où dans votre balisage. Voici un exemple de composant simple qui copie du texte dans le presse-papiers

Voir le Pen Démonstration de composant web simple par CSS GRID ( @cssgrid ) le CodePen

Une approche centrée sur les composants du développement frontal est devenue omniprésente, inaugurée par le cadre React de Facebook. Inévitablement, compte tenu de l'omniprésence des cadres dans les workflows frontaux modernes, un certain nombre d'entreprises ont construit des bibliothèques de composants en utilisant leur cadre de choix. Ces composants sont réutilisables uniquement dans ce cadre particulier.


 Un composant du Carbon Design System d'IBM
Un composant du Carbon Design System d'IBM. Pour utilisation dans les applications React uniquement. D'autres exemples significatifs de bibliothèques de composants construites dans React incluent Atlaskit d'Atlassian et Polaris de Shopify. ( Grand aperçu )

Il est rare qu'une grande entreprise ait une unité frontale uniforme et qu'il ne soit pas rare de la replater d'un cadre à l'autre. Les cadres vont et viennent. Pour activer le maximum de réutilisation potentielle à travers les projets, nous avons besoin de composants qui sont framework agnostic .


 Une capture d'écran de npmjs.com montrant des composants qui font la même chose construits exclusivement pour des frameworks javascript particuliers. ] La recherche de composants via <a href= npmjs.com
révèle un écosystème Javascript fragmenté. ( Grand aperçu )

 Un graphique montrant la popularité des frameworks au fil du temps. Ember, Knockout et Backbone ont plongé dans la popularité, remplacée par de nouvelles offres.
La popularité en constante évolution des cadres au fil du temps. ( Grand aperçu )

"J'ai construit des applications web en utilisant: Dojo, Mootools, Prototype, jQuery, Backbone, Thorax et React au cours des années … J'aurais aimé pouvoir apporter ce composant Dojo que j'ai asservi avec moi à mon application React d'aujourd'hui. "

Dion Almaer directeur de l'ingénierie, Google

Lorsque nous parlons d'un composant Web, nous parlons de la combinaison d'un élément personnalisé avec DOM ombre . Les éléments personnalisés et les DOM d'observation font partie de la spécification DOM du W3C et de la norme DOM du WHATWG – ce qui signifie que les composants Web sont une norme Web . Les éléments personnalisés et les DOM fantômes sont enfin configurés pour obtenir le support de plusieurs navigateurs cette année. En utilisant une partie standard de la plate-forme Web native, nous nous assurons que nos composants peuvent survivre au cycle rapide de restructurations frontales et de repenser l'architecture. Les composants Web peuvent être utilisés avec n'importe quel langage de modèle et tout framework frontal – ils sont véritablement compatibles entre eux et interopérables. Ils peuvent être utilisés partout à partir d'un blog WordPress à une application d'une seule page.


 Le projet Custom Elements Everywhere de Rob Dodson documente l'interopérabilité des composants Web avec divers frameworks JavaScript côté client.
Le projet
de Rob Dodson documente l'interopérabilité des composants Web avec divers frameworks Javascript côté client. Réagissez, la valeur aberrante ici, nous espérons résoudre ces problèmes avec React 17. ( Grand aperçu )

Création d'un composant Web

Définition d'un élément personnalisé

Il a toujours été possible de créer des noms de balises et d'afficher leur contenu sur la page.

 Hello World! 

HTML est conçu pour être tolérance de panne. Ce qui précède sera rendu, même si ce n'est pas un élément HTML valide. Il n'y a jamais eu de bonne raison de le faire – s'écarter des balises standardisées a traditionnellement été une mauvaise pratique. Cependant, en définissant une nouvelle balise à l'aide de l'API d'élément personnalisé, nous pouvons augmenter le HTML avec des éléments réutilisables dotés de fonctionnalités intégrées. Créer un élément personnalisé est très similaire à la création d'un composant dans React – mais ici s'étendaient HTMLElement .

 class ExpandableBox étend HTMLElement {
      constructeur () {
        super()
      }
    }

Un appel sans paramètre à super () doit être la première instruction du constructeur. Le constructeur doit être utilisé pour configurer les valeurs initiales d'état et par défaut et pour configurer les écouteurs d'événement. Un nouvel élément personnalisé doit être défini avec un nom pour sa balise HTML et la classe correspondante d'éléments:

 customElements.define ('expandable-box', ExpandableBox) 

C'est une convention pour mettre en majuscule les noms de classe. La syntaxe de la balise HTML est cependant plus qu'une convention. Et si les navigateurs voulaient implémenter un nouvel élément HTML et qu'ils voulaient l'appeler expandable-box? Pour éviter les conflits de noms, aucune nouvelle balise HTML standard ne comportera de tiret. En revanche, les noms des éléments personnalisés doivent comporter un tiret.

 customElements.define ('any', Whatever) // invalid
customElements.define ('what-ever', Whatever) // valide

Cycle de vie des éléments personnalisés

L'API propose quatre réactions personnalisées – fonctions qui peuvent être définies dans la classe et qui seront automatiquement appelées en réponse à certains événements du cycle de vie d'un élément personnalisé. 19659005] connectedCallback est exécuté lorsque l'élément personnalisé est ajouté au DOM.

 connectedCallback () {
    console.log ("l'élément personnalisé est sur la page!")
}

Cela inclut l'ajout d'un élément avec Javascript:

 document.body.appendChild (document.createElement ("expandable-box")) // "l'élément personnalisé est sur la page" 

ainsi que élément dans la page avec une balise HTML:

  // "élément personnalisé est sur la page" 

Tout travail impliquant l'extraction de ressources ou le rendu doit être ici.

disconnectedCallback est exécuté lorsque l'élément personnalisé est supprimé du DOM.

 disconnectedCallback () {
    console.log ("l'élément a été supprimé")
}
document.querySelector ("expandable-box"). remove () // "l'élément a été supprimé"

adoptedCallback est exécuté lorsque l'élément personnalisé est adopté dans un nouveau document. Vous n'avez probablement pas à vous soucier de celui-ci trop souvent.

attributeChangedCallback est exécuté lorsqu'un attribut est ajouté, modifié ou supprimé. Il peut être utilisé pour écouter les modifications apportées aux attributs natifs standardisés comme désactivé ou src ainsi que tous les attributs personnalisés que nous inventons. C'est l'un des aspects les plus puissants des éléments personnalisés car il permet la création d'une API conviviale.

Attributs d'éléments personnalisés

Il existe de nombreux attributs HTML. Afin que le navigateur ne perd pas de temps à appeler notre attributeChangedCallback quand n'importe quel attribut est modifié, nous devons fournir une liste des changements d'attributs que nous voulons écouter. Pour cet exemple, nous ne sommes intéressés que par un.

 static get observedAttributes () {
            retour ['expanded']
        }

Donc maintenant notre attributeChangedCallback ne sera appelé que lorsque nous changerons la valeur de l'attribut développé sur l'élément custom, car c'est le seul attribut que nous avons listé.

Les attributs HTML peuvent avoir des valeurs correspondantes (penser href, src, alt, valeur etc) alors que d'autres sont soit vrai soit faux (par exemple désactivé, sélectionné, requis ). Pour un attribut avec une valeur correspondante, nous inclurons ce qui suit dans la définition de la classe de l'élément personnalisé:

 get yourCustomAttributeName () {
  return this.getAttribute ('yourCustomAttributeName');
}
Définissez yourCustomAttributeName (nouvelleValeur) {
  this.setAttribute ('yourCustomAttributeName', nouvelleValeur);
}

Pour notre exemple d'élément, l'attribut sera soit vrai soit faux, donc la définition du getter et du setter est un peu différente.

 get expanded () {
  return this.hasAttribute ('développé')
}
        
// le second argument de setAttribute est obligatoire, donc nous utiliserons une chaîne vide
set étendu (val) {
  if (val) {
    this.setAttribute ('expanded', '');
  }
  autre {
    this.removeAttribute ('expanded')
  }
}

Maintenant que le standard a été traité, nous pouvons utiliser attributeChangedCallback .

 attributeChangedCallback (name, oldval, newval) {
  console.log (l'attribut `$ {name} a changé de $ {oldval} à $ {newval} !!`);
  // fait quelque chose chaque fois que l'attribut change
}

Traditionnellement, la configuration d'un composant Javascript impliquait de passer des arguments à une fonction init . En utilisant le attributeChangedCallback il est possible de créer un élément personnalisé qui est configurable juste avec le balisage

Les DOM Shadow et les éléments personnalisés peuvent être utilisés séparément, et vous pouvez trouver des éléments personnalisés tout seuls. Contrairement à l'ombre DOM, ils peuvent être polyfilled. Cependant, les deux spécifications fonctionnent bien conjointement.

Attacher un balisage et des styles avec le DOM Shadow

Jusqu'à présent, nous avons traité le comportement d'un élément personnalisé. En ce qui concerne le balisage et les styles, cependant, notre élément personnalisé est équivalent à un non-vide vide . Pour encapsuler HTML et CSS dans le cadre du composant, nous devons joindre un DOM d'ombre. Il est préférable de le faire dans la fonction constructeur.

 class FancyComponent extends HTMLElement {
        constructeur () {
            super()
            var shadowRoot = this.attachShadow ({mode: 'ouvert'})
            shadowRoot.innerHTML = `

bonjour monde!

`             }

Ne vous inquiétez pas de comprendre ce que signifie le mode – son standard, vous devez inclure, mais vous aurez toujours toujours vouloir ouvrir . Cet exemple simple rendra simplement le texte "hello world". Comme la plupart des autres éléments HTML, un élément personnalisé peut avoir des enfants – mais pas par défaut. Jusqu'à présent, l'élément personnalisé ci-dessus que nous avons défini ne rendra aucun enfant à l'écran. Pour afficher du contenu entre les balises, nous devons utiliser un élément slot .

 shadowRoot.innerHTML = `

Bonjour tout le monde!

`

Nous pouvons utiliser une balise de style pour appliquer du code CSS au composant.

 shadowRoot.innerHTML =

bonjour monde!

du contenu par défaut `

Ces styles ne s'appliqueront qu'au composant, nous sommes donc libres d'utiliser des sélecteurs d'éléments sans que les styles n'affectent quoi que ce soit d'autre de la page. Cela simplifie l'écriture de CSS, rendant inutiles les conventions de dénomination comme BEM

Publication d'un composant sur NPM

Les paquetages NPM sont publiés via la ligne de commande. Ouvrez une fenêtre de terminal et déplacez-vous dans un répertoire que vous souhaitez transformer en un package réutilisable. Tapez ensuite les commandes suivantes dans le terminal:

  1. Si votre projet n'a pas encore de package.json npm init vous guidera dans la génération d'un.
  2. npm adduser relie votre ordinateur à votre compte NPM. Si vous n'avez pas de compte préexistant, il en créera un nouveau.
  3. npm publish

 Les paquets NPM sont publiés via la ligne de commande
Grand aperçu

Si tout va bien, vous avez maintenant avoir un composant dans le registre NPM, prêt à être installé et utilisé dans vos propres projets – et partagé avec le monde entier.


 Un exemple de composant dans le registre NPM, prêt à être installé et utilisé dans vos propres projets. 19659094] Grand aperçu </a><br />
 </figcaption></figure>
<p> L'API des composants Web n'est pas parfaite. Les éléments personnalisés ne peuvent actuellement pas <a href= inclure des données dans les soumissions de formulaire
. L'histoire de l'amélioration progressive n'est pas géniale. Traiter de l'accessibilité n'est pas aussi facile qu'il devrait être .

Bien qu'initialement annoncé en 2011, le support du navigateur n'est toujours pas universel. Le support de Firefox est attendu plus tard cette année. Néanmoins, certains sites internet de haut niveau (comme Youtube) en font déjà usage. Malgré leurs défauts actuels, universellement composants partageables ils sont l'option singulière et dans l'avenir nous pouvons nous attendre des ajouts passionnants à ce qu'ils ont à offrir.

 Éditorial Smashing ] (il, ra, yk)




Source link