Appearance
Comment créer et utiliser des Web Components ?
Qu'est-ce qu'un Web Component ?
Les Web Components représentent un ensemble de technologies web standards permettant de créer des éléments HTML personnalisés, réutilisables et encapsulés. Imaginez-les comme des briques LEGO pour le web : une fois créés, vous pouvez les réutiliser partout, indépendamment de la technologie utilisée.
Un Web Component est composé de trois technologies principales :
- Custom Elements : Permet de créer de nouvelles balises HTML personnalisées
- Shadow DOM : Isole le style et le comportement du composant du reste de la page
- HTML Templates : Définit le contenu HTML qui sera utilisé dans le composant
Pourquoi utiliser les Web Components ?
- Réutilisabilité : Créez une fois, utilisez partout (React, Vue, Angular ou vanilla JavaScript)
- Encapsulation : Les styles et le comportement sont isolés du reste de l'application
- Standardisation : Basé sur les standards du web, donc compatible avec tous les navigateurs modernes
- Maintenabilité : Une seule source de vérité pour vos composants partagés
Par exemple, imaginons que vous ayez développé un composant de carte utilisateur sophistiqué dans votre application Angular, avec des animations, un style unique et des fonctionnalités spécifiques. Au lieu de le recréer pour chaque projet ou framework, vous pouvez le transformer en Web Component et l'utiliser simplement ainsi :
html
<user-card name="John Doe" role="admin"></user-card>
Dans ce tutoriel, nous allons voir comment transformer un composant Angular en Web Component réutilisable.
Installation
Avant de commencer, assurez-vous d'avoir installé les dépendances nécessaires :
bash
npm install @angular/elements
Création d'un Web Component
Commençons par créer un composant utilisateur simple :
ts
@Component({
selector: 'app-user',
standalone: true,
template: `
<div class="user-card">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
`,
styles: [`
.user-card {
padding: 1rem;
border: 1px solid #ccc;
border-radius: 4px;
}
`]
})
export class UserComponent {
@Input() user!: User;
}
CONSEIL
Utilisez toujours le décorateur @Input()
pour les propriétés que vous souhaitez exposer dans votre Web Component.
Configuration du Web Component
Pour transformer notre composant en Web Component, nous devons modifier le fichier main.ts
. Examinons en détail chaque partie importante :
ts
import { createApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { UserComponent } from './app/components/features/user/user.component';
import { ApplicationRef } from '@angular/core';
import { createCustomElement } from '@angular/elements';
(async () => {
const app: ApplicationRef = await createApplication(appConfig);
// Définition du Web Component
const userElement = createCustomElement(UserComponent, {
injector: app.injector
});
// Enregistrement du Web Component
customElements.define('user-card', userElement);
})();
L'injector
est un concept fondamental dans Angular qui gère l'injection de dépendances. Quand nous créons un Web Component, nous devons lui fournir un injecteur pour qu'il puisse :
- Accéder aux services Angular
- Gérer le cycle de vie des composants
- Résoudre les dépendances nécessaires
ts
const userElement = createCustomElement(UserComponent, {
injector: app.injector
});
INJECTION
L'utilisation de app.injector
permet à votre Web Component d'avoir accès à tous les services définis au niveau de l'application Angular.
La méthode customElements.define()
est une API web standard qui permet d'enregistrer un nouvel élément personnalisé dans le navigateur. Elle prend deux paramètres :
- Le nom de la balise HTML (qui doit contenir un tiret)
- La classe du composant personnalisé
ts
customElements.define('user-card', userElement);
CONVENTION DE NOMMAGE
Le nom du custom element DOIT :
- Contenir un tiret (-) pour éviter les conflits avec les éléments HTML natifs
- Être en minuscules
- Ne pas commencer par un chiffre
Exemple d'utilisation dans différents contextes
Une fois enregistré, votre Web Component peut être utilisé de différentes manières :
Dans un projet Angular :
ts
@Component({
selector: 'app-root',
template: `
<user-card [user]="currentUser"></user-card>
`
})
Dans un projet React :
jsx
function App() {
return (
<user-card user={currentUser}></user-card>
);
}
En HTML vanilla :
html
<user-card id="user1"></user-card>
<script>
document.querySelector('user-card').user = {
id: 1,
name: 'John Doe'
};
</script>
Je vais améliorer la fin du tutoriel en expliquant plus en détail ces aspects :
Build et Distribution
Pour distribuer votre Web Component, vous devrez créer un build spécifique. Voici la configuration recommandée dans votre package.json
:
json
{
"scripts": {
"build:elements": "ng build --configuration production --output-hashing none"
}
}
POURQUOI --output-hashing NONE ?
L'option --output-hashing none
est importante car :
- Elle empêche Angular d'ajouter des hashes dans les noms de fichiers
- Permet d'avoir des noms de fichiers constants entre les builds
- Facilite l'intégration dans d'autres projets qui référencent directement ces fichiers
Optimisation avec ngx-build-plus
ngx-build-plus
est un outil qui améliore le processus de build des Web Components Angular :
bash
npm install ngx-build-plus --save-dev
Cet outil offre plusieurs avantages :
- Build modulaire : Permet de créer des bundles séparés pour chaque Web Component
- Lazy Loading : Charge les composants uniquement quand ils sont nécessaires
- Réduction de taille : Optimise le bundle final en excluant les dépendances non utilisées
json
{
"projects": {
"your-project": {
"architect": {
"build": {
"builder": "ngx-build-plus:browser",
"options": {
"singleBundle": true,
"keepPolyfills": false
}
}
}
}
}
}
OPTIMISATION AVANCÉE
Pour une distribution optimale, vous pouvez :
- Créer des bundles séparés pour chaque Web Component
- Utiliser la compression Gzip/Brotli
- Mettre en place un système de versioning
Distribution et Déploiement
Vous pouvez lire comment créer une librairie Angular et la publier sur NPM.
Une fois buildé, votre Web Component peut être distribué de plusieurs façons :
- NPM Package :
bash
npm publish
- CDN :
html
<script src="https://unpkg.com/your-web-component"></script>
- Hébergement personnalisé :
html
<script src="https://your-domain.com/elements/user-card.js"></script>
COMPATIBILITÉ
N'oubliez pas d'inclure les polyfills nécessaires pour les navigateurs plus anciens :
html
<script src="https://unpkg.com/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>