Nous implémentons des composants angulaires dans React, Vue et même jQuery si vous le souhaitez

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'; // Import your AvatarModule import { AvatarModule } from 'ngx-avatar'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, // Specify AvatarModule as an import AvatarModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } 

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) { //    Angular Element const avatarComponent = createCustomElement(AvatarComponent, { injector }); //     customElements.define('avatar-lib', avatarComponent); } ngDoBootstrap() {} } 

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-vue

Il est temps pour React! Tout est aussi simple:

 <avatar-lib name = {this.myName}></avatar-lib> 

Démo sur React

Eh bien, en général, le projet

En ce qui concerne le support du navigateur pour le moment:

https://angular.io/guide/elements#browser-support-for-custom-elements
https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define

Bien 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 .

Source: https://habr.com/ru/post/fr432664/


All Articles