Réutilisez vos composants Angular hors de l'écosystème Angular grâce à Angular Elements et aux standards Web Components.
Installation et configuration
Angular Elements est le package officiel qui permet de transformer n'importe quel composant Angular en Web Component natif (Custom Element), utilisable dans une page HTML, React, Vue ou tout autre contexte.
ng add @angular/elements
Le CLI ajoute @angular/elements et document-register-element (polyfill si nécessaire). Crée ensuite un projet dédié au packaging :
ng generate application mon-widget --standalone
Créer et enregistrer un Web Component
Le composant Angular reste un composant standard. C'est dans le main.ts (ou AppModule) qu'on le transforme en Custom Element avec createCustomElement().
// widget-compteur.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-compteur',
standalone: true,
template: `
<div class="compteur">
<span>{{ valeur }}</span>
<button (click)="incrementer()">+</button>
</div>
`,
styles: ['.compteur { display: flex; gap: 8px; align-items: center; }']
})
export class CompteurComponent {
@Input() valeur = 0;
@Output() change = new EventEmitter<number>();
incrementer(): void {
this.valeur++;
this.change.emit(this.valeur);
}
}
// main.ts — enregistrement du Custom Element
import { createApplication } from '@angular/platform-browser';
import { createCustomElement } from '@angular/elements';
import { CompteurComponent } from './app/widget-compteur.component';
(async () => {
const app = await createApplication();
const CompteurElement = createCustomElement(CompteurComponent, {
injector: app.injector
});
customElements.define('af-compteur', CompteurElement);
})();
Le widget est maintenant utilisable dans n'importe quelle page HTML :
<script src="af-compteur.js"></script>
<af-compteur valeur="5"></af-compteur>
Inputs, outputs et cycle de vie
Angular Elements mappe automatiquement les @Input() en attributs HTML et les @Output() en événements DOM personnalisés (CustomEvent).
// Écouter l'événement depuis JavaScript vanilla
const el = document.querySelector('af-compteur');
el.addEventListener('change', (event) => {
console.info('Nouvelle valeur:', event.detail);
});
// Modifier un input dynamiquement
el.setAttribute('valeur', '10');
// ou directement via la propriété JS
el.valeur = 10;
Attributs vs propriétés
- Les attributs HTML sont toujours des chaînes — Angular Elements coerce automatiquement vers le type du
@Input(). - Les propriétés JS acceptent n'importe quel type (objet, tableau…) et ne passent pas par le DOM.
Styles et encapsulation CSS
Par défaut, Angular utilise l'Emulated Encapsulation — les styles sont scopés via des attributs générés. Pour un vrai Shadow DOM, change l'encapsulation du composant.
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-compteur',
standalone: true,
encapsulation: ViewEncapsulation.ShadowDom, // vrai Shadow DOM
template: `...`,
styles: [`
:host { display: block; font-family: sans-serif; }
button { background: var(--af-primary, #6c63ff); color: white; }
`]
})
export class CompteurComponent {}
--af-primary, --af-size…). Les consommateurs peuvent ainsi styler le widget sans casser l'encapsulation Shadow DOM.
Bundle et optimisation taille
Le principal inconvénient d'Angular Elements est la taille du bundle — Angular runtime est embarqué. Quelques stratégies pour réduire l'impact :
# Build de production avec optimisation maximale
ng build --configuration production --output-hashing=none
# Concaténer tous les fichiers en un seul JS
cat dist/mon-widget/browser/*.js > af-compteur.js
- Standalone components — évite le surcoût de
NgModule, réduit le bundle de 5–15 kB. - Partager le runtime Angular — si plusieurs widgets sont chargés sur la même page, utilise un
externalswebpack ou un import map pour partager le runtime. - Lazy loading des dépendances — charge les sous-modules Angular (
HttpClient,Router…) uniquement si le widget en a besoin. - Zone.js optionnel — en mode zoneless (Angular 18+), supprime zone.js du bundle (~35 kB gzippé).
Quand utiliser Angular Elements
- Partager un widget métier complexe (graphique, formulaire multi-étapes) entre plusieurs applications de stacks différentes.
- Intégrer un composant Angular dans un CMS (WordPress, Drupal) ou un portail legacy sans migrer toute l'application.
- Exposer des composants de design system à des équipes non-Angular tout en gardant un seul code source.
- Ne pas utiliser Angular Elements si l'application consommatrice est elle-même Angular — préfère alors une lib partagée dans un monorepo.
- Documenter l'API du widget (attributs, événements, CSS variables) dans un README versionné pour les équipes consommatrices.
- Tester le Web Component dans un contexte sans Angular (page HTML vanilla) avant de le publier.