Composants Web avec Angular Elements

Web Components – Pourquoi ?

Au début de ma carrière, nous travaillions principalement avec Joomla. Avec le temps, de nombreuses demandes spécifiques et idées propres sont apparues, ce qui a conduit au développement de modules personnalisés pour Joomla. Au fil des années, d’autres CMS comme Contao et WordPress se sont ajoutés, ce qui nous a confrontés à un problème majeur : le code de nos modules Joomla ne pouvait être repris que partiellement pour d’autres CMS. Et ce n’est pas tout : chaque portage impliquait un nouveau projet à maintenir et à mettre à jour. Alors, que faire ?

C’est là que les Web Components entrent en jeu. Ils sont indépendants de la plateforme et pris en charge par tous les navigateurs modernes. Plus besoin de solutions spécifiques à chaque CMS et un seul projet à maintenir. Transformer le module en Web Component devient alors une évidence.

Qu’est-ce que les Web Components ?

Les Web Components sont une technologie qui permet aux développeurs de créer des éléments réutilisables dont le code s’exécute de manière encapsulée, indépendamment du DOM principal. Trois technologies principales sont utilisées :

Custom Elements

Les Custom Elements permettent aux développeurs de définir leurs propres balises HTML et leur fonctionnalité.

Shadow DOM

Bien que les Web Components apparaissent dans le DOM, ils sont en réalité rendus dans le Shadow DOM. Cet arbre DOM est attaché au DOM principal et garantit que le code du composant est isolé du reste du document.

Templates HTML & Slots

Les templates permettent de créer des structures de balisage réutilisables, tandis que les slots définissent où et comment le contenu est inséré dans ces templates.

Création du projet Angular

La première étape consiste bien entendu à créer le projet Angular. Cela se fait très simplement avec la commande suivante :

ng new <nom-du-projet> --no-standalone

Bien qu’Angular prenne en charge les Web Components nativement, les bibliothèques nécessaires ne sont pas ajoutées automatiquement lors de la création du projet. Elles doivent être installées manuellement avec la commande suivante :

npm i @angular/elements

Le projet est maintenant prêt à être transformé en Web Component.

Conversion du projet en Web Component

app.module.ts

La première étape consiste à adapter le fichier app.module.ts. La classe est étendue avec le hook Angular DoBootstrap, et un injector est ajouté via le constructeur afin de définir notre Custom Element.

À l’intérieur du hook ngDoBootstrap, le Web Component est défini et rendu disponible. La fonction createCustomElement permet de créer un Custom Element basé sur un composant Angular (dans notre cas, AppComponent). La fonction customElements.define permet ensuite de définir la balise HTML utilisée pour insérer le Web Component dans le DOM. Lors du choix du nom de la balise, les règles suivantes doivent être respectées :

  • Le nom de la balise doit commencer par une lettre minuscule (a–z).
  • Le nom de la balise doit contenir au moins un tiret (-).
  • Les balises HTML existantes ne peuvent pas être utilisées.
  • Le nom de la balise ne doit pas contenir de symboles (=, @, $, etc.).

Cette page sur webcomponents.guide propose un outil de vérification des noms ainsi qu’une description détaillée des règles.

export class AppModule implements DoBootstrap {
  constructor(readonly injector: Injector) {}

  ngDoBootstrap(): void {
    const webArticle = createCustomElement(AppComponent, {
      injector: this.injector,
    });

    customElements.define('web-article', webArticle);
  }
}

Pour terminer, la ligne suivante doit être supprimée afin d’éviter l’erreur Angular NG05104 :

bootstrap: [AppComponent]

Extension de main.ts

Après l’adaptation de app.module.ts, le fichier main.ts doit également être modifié comme suit afin d’éviter l’erreur Angular NG0908 :

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import 'zone.js';

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

Compiler le Web Component

Pour pouvoir utiliser le composant, il faut générer un build avec la commande suivante :

ng build --output-hashing none

Notez l’utilisation de --output-hashing none.

Par défaut, Angular ajoute un nouveau hash au nom du fichier main généré à chaque build. Comme le fichier est importé par son nom, il est plus simple de gérer les mises à jour lorsque le hash est désactivé.

Il est également possible de définir un script dans le fichier package.json.

Après la compilation, le code généré se trouve à l’emplacement suivant :

<répertoire-du-projet>/dist/<nom-du-projet>/browser/main.js

Intégration du Web Component

Un Web Component s’intègre dans un site web en trois étapes :

  • Téléverser le fichier main.js généré.
  • Inclure main.js via une balise script.
  • Insérer le Web Component à l’aide de la balise définie dans app.module.ts.

Ces étapes peuvent varier légèrement selon le système utilisé.

HTML5

L’intégration d’un Web Component dans une page HTML5 statique est très simple. Il suffit d’ajouter une balise script dans le head du fichier HTML pointant vers main.js. Le Web Component peut ensuite être inséré via la balise définie :

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Angular Social Feed</title>
  <script src="web-article/dist/web-article/browser/main.js"></script>
</head>
<body>
  <web-article></web-article>
</body>
</html>

Contao

Pour utiliser des Web Components avec Contao, le fichier main.js est téléversé via l’interface d’administration dans un dossier public. Il peut ensuite être intégré via un layout de page (Thèmes → Layouts de page) en utilisant l’option JavaScripts externes.

Le Web Component est alors disponible sur toutes les pages utilisant ce layout et peut être inséré à n’importe quel endroit via un module ou un bloc HTML.

Lors de l’insertion via un élément de contenu, il est recommandé d’utiliser HTML non filtré. Sinon, Contao peut remplacer les chevrons de la balise par des entités HTML, ce qui afficherait uniquement le nom de la balise.

Joomla

Après avoir téléversé main.js via FTP, le fichier doit être ajouté dans le head du template. Les templates Joomla proposent généralement cette option directement dans les paramètres du template (Système → Styles des templates du site → Template).

Si le template ne propose pas cette option, main.js peut être ajouté via le fichier index.php du template, modifiable sous Système → Templates du site → Template.

Attention : cette méthode ne doit être utilisée qu’en dernier recours. Il est déconseillé de modifier les fichiers principaux d’un template, car ces changements peuvent être écrasés lors d’une mise à jour.

Une fois main.js inclus dans le head, le Web Component peut être inséré dans la page via sa balise définie, par exemple à l’aide d’un module personnalisé.

WordPress

L’intégration d’un Web Component dans WordPress est un peu plus complexe, car le fichier main.js doit être importé après son téléversement. Commencez par téléverser le fichier dans le répertoire suivant :

<WP-ROOT>/wp-content/themes/<THÈME>/<DOSSIER-PERSONNALISÉ>/

Une fois le fichier téléversé, un script d’import doit être ajouté. Cela peut se faire via l’interface d’administration sous Outils → Éditeur de fichiers du thème. Sélectionnez le thème concerné, puis ajoutez le code suivant dans le fichier functions.php :

function add_webcomponent() {
  wp_register_script(
    'web-component-script',
    get_template_directory_uri() . '/web-component/main.js'
  );

  wp_enqueue_script('web-component-script');
}

add_action('wp_enqueue_scripts', 'add_webcomponent');

Cette fonction PHP add_webcomponent enregistre un nouveau script nommé web-component-script, qui importe le fichier main.js dans la page WordPress et l’exécute. La fonction est appelée automatiquement via un hook WordPress. Les noms add_webcomponent et web-component-script peuvent être choisis librement.

Une fois cette fonction ajoutée, le Web Component peut être inséré dans une page WordPress, par exemple via un bloc HTML personnalisé.

Back to top

Sprache: