Composants Web avec Angular

Biig
3 min readSep 17, 2019

--

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 createCustomElementfourni par le nouveau package @angular/elementspour 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.jspour 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.

--

--

Biig

Conseil, conception et réalisation de stratégies digitales. we think _ we build — https://biig.fr/