Un composant web est un élément personnalisé et réutilisable. Dans nos applications Angular, un composant peut correspondre à une page entière ou un élément de l’interface (menu, header, modal, datepicker, etc…). On parle ici de “composant Angular” et non de “composant Web”.
Le but de cet article est de vous montrez comment extraire tout composant construit à l’aide d’Angular pour l’utiliser dans n’importe quelle application web.
Voici un composant Angular :
@Component({
selector: 'app-mon-composant',
template: 'Mon composant Angular'
})
export class MonComposantComponent { }
Il suffit ensuite d'insérer dans un template de notre application Angular la balise suivante pour afficher le composant :
<app-mon-composant></app-mon-composant>
Cependant, ce composant ne peut pas fonctionner en dehors d'Angular.
Voici donc la marche à suivre...
Installer les packages
npm i @angular/elements --save
npm i @webcomponents/custom-elements --save
Importer les polyfills
import "@webcomponents/custom-elements/src/native-shim";
import "@webcomponents/custom-elements/custom-elements.min";
Ajouter le Shadow DOM à votre composant
@Component({
selector: 'app-mon-composant',
template: 'Mon composant Angular',
encapsulation: ViewEncapsulation.ShadowDom
})
export class MonComposantComponent { }
Le shadow DOM va permette d’avoir une encapsulation propre au composant, le DOM sera isolé du DOM principal de l’application.
Mise à jour du module principal
import { NgModule, Injector } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { createCustomElement } from '@angular/elements';import { MonComposantComponent } from './mon-composant/mon-composant.component';@NgModule({
imports: [BrowserModule],
declarations: [MonComposantComponent],
entryComponents: [MonComposantComponent]
})
export class AppModule {
constructor(private injector: Injector) {} ngDoBootstrap(): void {
this.createWebComponent(MonComposantComponent, 'mon-composant');
} createWebComponent(component, name: string) {
const el = createCustomElement(component, {
injector: this.injector
});
customElements.define(name, el);
}
}
Nous utilisons ici la méthode createCustomElement
fourni par le nouveau package @angular/elements
pour convertir notre composant Angular en composant web natif.
Création du package simplifié
Nous allons modifier dans le fichier angular.json la configuration de prod :
...
"outputHashing": "none",
"extractCss": false,
...
Puis créer un fichierbuild.js
pour regrouper les fichiers javascript en un seul :
const fs = require('fs');
const concat = require('concat');const distFolder = './dist/';(function build() {
concatFile();
})();function concatFile() {
const files = [
distFolder + 'runtime.js',
distFolder + 'polyfills.js',
distFolder + 'main.js'
]; concat(files, distFolder + 'component.js');
}
Il ne reste plus qu’à builder avec la commande ng build --prod && node build.js
.
Vous pouvez désormais utilisez votre composant comme s’il s’agissait d’un élément standard, voici un exemple :
<mon-composant></mon-composant>
<script src="component.js"></script>
Bonus : les input et output sont pris en charges, nous pouvons donc communiquer comme sur une application Angular. Voici un exemple :
<mon-composant my-input="value"></mon-composant>
<script src="component.js"></script>
<script>
const component = document.querySelector('mon-composant');
component.addEventListener('myOutputName', function(event) { });
</script>
Attention pour un usage en production, les composants Web ne sont pas supportés par tous les navigateurs, les polyfills assureront la compatibilité mais vous n’aurez pas de Shadow DOM.
Retrouvez aussi cet article sur : https://www.biig.fr/nous-sommes-inventifs/biigbox/composants-web-avec-angular