Si vous avez trouvé un composant sympa dans npm, mais avec le préfixe ng, ngx, angular et ainsi de suite, alors ne vous inquiétez pas. Il existe de nombreuses solutions pour obtenir ce composant. Dans cet article, nous considérerons une solution officiellement prise en charge par l'équipe angulaire, à savoir les éléments angulaires.
Pour vous entraîner, choisissez n'importe quel composant dans
Awesome Angular .
J'ai choisi un
avatar simple, mais très intéressant -
ngx . Qui, à son tour, affiche les avatars de divers réseaux sociaux ou affiche simplement les initiales de l'utilisateur.
Quelque chose comme ça:

Et il a une API simple, voici un petit exemple:
<ngx-avatar facebookId="1508319875"></ngx-avatar> <ngx-avatar src="assets/avatar.jpg"></ngx-avatar> <ngx-avatar name="John Doe"></ngx-avatar>
Et donc, créez un projet angulaire pour cela et connectez la bibliothèque.
ng new avatar-lib --minimalN npm i ngx-avatar --save
Connectez le package à notre module.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component';
Créons maintenant un composant simple, car par défaut, le `AvatarModule` n'exporte pas son seul composant.
ng gc avatar
import { Component, ViewEncapsulation, Input } from '@angular/core'; @Component({ selector: 'app-avatar', template: ` <ngx-avatar [name]="name"></ngx-avatar> `, styles: [], encapsulation: ViewEncapsulation.ShadowDom }) export class AvatarComponent { @Input() name: string; constructor() { } }
Pour simplifier, nous n'avons utilisé qu'un seul des paramètres d'entrée.
Nous allons créer un composant universel à partir de tout cela. Pour que nos éléments fonctionnent, vous devez ajouter des éléments angulaires à notre projet.
ng add @angular/elements
Entre autres choses, cette commande inclura également dans la section des scripts une version allégée pour l'enregistrement des éléments personnalisés.
"scripts": [{ "input": "node_modules/document-register-element/build/document-register-element.js" }]
Le fichier app.module.ts résultant:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule, Injector } from '@angular/core'; import { createCustomElement } from '@angular/elements'; import { AvatarComponent } from './avatar.component'; import { AvatarModule } from 'ngx-avatar'; @NgModule({ declarations: [AvatarComponent], imports: [AvatarModule, BrowserModule], entryComponents: [AvatarComponent] }) export class AppModule { constructor(private injector: Injector) {
Super! Maintenant, nous devons collecter tout ce bien. Pour ce faire, créez votre propre collecteur qui regroupera notre composant dans un fichier js:
const fs = require('fs-extra'); const concat = require('concat'); (async function build() { const files = [ './dist/avatar-lib/runtime.js', './dist/avatar-lib/polyfills.js', './dist/avatar-lib/scripts.js', './dist/avatar-lib/main.js' ]; await fs.ensureDir('elements'); await concat(files, 'elements/avatar-lib.js'); })();
Tout est prêt! il ne reste plus qu'à collecter. Ajoutez un tel script à notre package.json.
"build:elements": "ng build --prod --output-hashing none && node build.js"
Eh bien, c'est tout! Nous avons un tel fichier js `avatar-lib.js` pesant ~ 221kB et ~ 60kb en gzip. Naturellement, beaucoup plus sont inclus ici avec
angular / core. Le ngx-avatar lui-même pèse environ 16,8 Ko et 5,4 Ko en gzip. Pour réduire considérablement le poids de avatar-lib.js, nous aurions besoin d'Ivy Compiler, mais c'est un sujet pour un autre article. (J'espère qu'Ivy sera publié d'ici là, ou je collecterai manuellement ce qui est maintenant disponible).
Que nous a apporté Angular Elements?
Ceci est juste une API pratique pour implémenter des composants Web. En fait, on pourrait s'en passer. Voyez ce que vous pourriez faire plus tôt:
un article de Jia Li (accompagne activement Zone.js maintenant) .
Nous intégrons notre composant dans d'autres cadres.
Première vue. Nous nous connectons de la manière qui vous convient et insérons avatar-lib dans le modèle, transférons les données via des vues standard.
<avatar-lib :name = 'myName'></avatar-lib>
Il serait également possible d'organiser des événements de sortie.
Démo Vue:
https://github.com/Jamaks/angular-element/tree/master/ang-el-vueIl est temps pour React! Tout est aussi simple:
<avatar-lib name = {this.myName}></avatar-lib>
Démo sur ReactEh bien, en général, le projetEn ce qui concerne le support du navigateur pour le moment:
https://angular.io/guide/elements#browser-support-for-custom-elementshttps://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/defineBien sûr, c'est à vous de décider d'utiliser ou non une telle méthode d'implémentation. Je voudrais que les composants de l'interface utilisateur ne soient attachés à rien et sans suffixes similaires: ng-, ngx-, v-, react-, rc- et ainsi de suite.
Bonus!Inspiré par la taille du composant (ngx-avatar), j'ai quand même essayé d'alimenter ngtsc, ngcc puis de l'assembler à l'aide du rollup. Mais les tentatives ont échoué, car le composant sélectionné nécessitait de nombreux modules externes. Désespéré, a fait un semblant de ce composant, et les résultats m'ont agréablement surpris - pour le moment (7.1.2), la bibliothèque était ~ 96kb et ~ 26kb en gzip. Naturellement, il y avait beaucoup de dépendances, et ma configuration de cumul laisse beaucoup à désirer. Mais encore, ce n'est pas le 3kb qu'on nous a montré lors de la présentation d'Ivy. Il reste à prévoir lorsqu'ils déploient ngcc sur Webpack (cli) et écrivent de la documentation.
Vous pouvez également
trouver de petites expériences et des initiés du monde angulaire
ici .