Implementamos componentes angulares en React, Vue e incluso jQuery si lo desea

Si encontró un componente genial en npm, pero con el prefijo ng, ngx, angular, etc., no se preocupe por esto. Hay muchas soluciones para obtener este componente. En este artículo, consideraremos una solución que cuenta con el apoyo oficial del Equipo Angular, a saber, Elementos Angulares.

Para practicar, elija cualquier componente de Awesome Angular .

Elegí un simple, pero muy interesante: ngx-avatar . Lo que, a su vez, muestra avatares de varias redes sociales o simplemente muestra las iniciales del usuario.
Algo como esto:


Y tiene una API simple, aquí hay un pequeño ejemplo:

<ngx-avatar facebookId="1508319875"></ngx-avatar> <ngx-avatar src="assets/avatar.jpg"></ngx-avatar> <ngx-avatar name="John Doe"></ngx-avatar> 

Y así, cree un proyecto angular para esto y conecte la biblioteca.

 ng new avatar-lib --minimalN npm i ngx-avatar --save 

Conecte el paquete a nuestro módulo.

 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 { } 

Ahora creemos un componente simple, porque por defecto el `AvatarModule` no exporta su único componente.

 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() { } } 

Para simplificar, utilizamos solo uno de los parámetros de entrada.

Crearemos un componente universal a partir de todo esto. Para que nuestros elementos funcionen, debe agregar elementos angulares a nuestro proyecto.

 ng add @angular/elements 

Entre otras cosas, este comando también incluirá en la sección de scripts una versión lite para registrar elementos personalizados.

 "scripts": [{ "input": "node_modules/document-register-element/build/document-register-element.js" }] 

El app.module.ts resultante:

 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() {} } 

Genial Ahora necesitamos recolectar todo este bien. Para hacer esto, cree su propio recopilador que empaquetará nuestro componente en un archivo 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'); })(); 

Todo esta listo! solo queda por recoger. Agregue tal script a nuestro paquete.json.

 "build:elements": "ng build --prod --output-hashing none && node build.js" 

Bueno, eso es todo! Tenemos un archivo js `avatar-lib.js` que pesa ~ 221kB y ~ 60kb en gzip. Naturalmente, se incluyen muchos más aquí con angular / núcleo. El ngx-avatar pesa alrededor de 16.8kB y 5.4kB en gzip. Para reducir en gran medida el peso de avatar-lib.js necesitaríamos el Compilador Ivy, pero este es un tema para otro artículo. (Espero que Ivy sea lanzado en este momento, o recolectaré manualmente de lo que ahora está disponible).

¿Qué nos dieron los Elementos Angulares?

Esta es solo una práctica API para implementar componentes web. De hecho, uno podría prescindir de él. Vea lo que podría hacer antes: un artículo de Jia Li (ahora acompaña activamente a Zone.js) .

Incorporamos nuestro componente en otros marcos.

Primero en Vue. Nos conectamos de cualquier manera conveniente para usted e insertamos avatar-lib en la plantilla, transferimos los datos a través de vue bings estándar.

 <avatar-lib :name = 'myName'></avatar-lib> 

También sería posible organizar eventos de salida.

Vue demo: https://github.com/Jamaks/angular-element/tree/master/ang-el-vue

¡Es hora de reaccionar! Todo es igual de simple:

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

Demo en React

Bueno, en general, el proyecto

En cuanto al soporte del navegador en este momento:

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

Por supuesto, depende de usted decidir si utilizar dicho método de implementación. Me gustaría que los componentes de la interfaz de usuario no se unan a nada y que no tengan sufijos similares: ng-, ngx-, v-, react-, rc-, etc.

Bonus!

Inspirado por el tamaño del componente (ngx-avatar), aún intenté alimentar a ngtsc, ngcc y luego ensamblarlo usando un paquete acumulativo. Pero los intentos no tuvieron éxito, ya que el componente seleccionado requería muchos módulos externos. Desesperado, se parecía un poco a este componente, y los resultados me sorprendieron gratamente: en este momento (7.1.2), la biblioteca tenía ~ 96 kb y ~ 26 kb en gzip. Naturalmente, había muchas dependencias, y mi configuración de resumen deja mucho que desear. Pero aún así, este no es el 3kb que se nos mostró durante la presentación de Ivy. Es de esperarse cuando implementan ngcc en Webpack (cli) y escriben documentación.

También puedes encontrar pequeños experimentos y personas del mundo angular aquí .

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


All Articles