Se você encontrou um componente interessante em npm, mas com o prefixo ng, ngx, angular e assim por diante, não se preocupe com isso. Existem muitas soluções para obter esse componente. Neste artigo, consideraremos uma solução oficialmente suportada pela equipe angular, a saber, elementos angulares.
Para praticar, escolha qualquer componente em
Awesome Angular .
Eu escolhi um
avatar simples, mas muito interessante -
ngx . Que, por sua vez, exibe avatares de várias redes sociais ou simplesmente exibe as iniciais do usuário.
Algo assim:

E ele tem uma API simples, aqui está um pequeno exemplo:
<ngx-avatar facebookId="1508319875"></ngx-avatar> <ngx-avatar src="assets/avatar.jpg"></ngx-avatar> <ngx-avatar name="John Doe"></ngx-avatar>
E assim, crie um projeto Angular para isso e conecte a biblioteca.
ng new avatar-lib --minimalN npm i ngx-avatar --save
Conecte o pacote ao nosso módulo.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component';
Agora vamos criar um componente simples, porque por padrão o `AvatarModule` não exporta seu ú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, usamos apenas um dos parâmetros de entrada.
Criaremos um componente universal a partir de tudo isso. Para que nossos elementos funcionem, você precisa adicionar elementos angulares ao nosso projeto.
ng add @angular/elements
Entre outras coisas, este comando também incluirá na seção de scripts uma versão lite para registrar os Elementos Personalizados.
"scripts": [{ "input": "node_modules/document-register-element/build/document-register-element.js" }]
O 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) {
Ótimo! Agora precisamos coletar tudo isso de bom. Para fazer isso, crie seu próprio coletor que compactará nosso componente em um arquivo 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'); })();
Está tudo pronto! resta apenas coletar. Adicione esse script ao nosso package.json.
"build:elements": "ng build --prod --output-hashing none && node build.js"
Bem, é isso! Temos um arquivo js `avatar-lib.js` pesando ~ 221kB e ~ 60kb no gzip. Naturalmente, muitos mais estão incluídos aqui com
angular / core. O próprio ngx-avatar pesa cerca de 16,8kB e 5,4kB em gzip. Para reduzir bastante o peso do avatar-lib.js, precisaríamos do Ivy Compiler, mas este é um tópico para outro artigo. (Espero que Ivy seja lançada nesse momento ou colecionarei manualmente o que já está disponível).
O que os elementos angulares nos deram?
Esta é apenas uma API útil para implementar componentes da Web. De fato, alguém poderia ficar sem ele. Veja o que você poderia fazer anteriormente:
um artigo de Jia Li (acompanha ativamente o Zone.js agora) .
Incorporamos nosso componente em outras estruturas.
Primeiro no Vue. Nós nos conectamos de qualquer maneira conveniente para você e inserimos avatar-lib no modelo, transferimos os dados através de vue bings padrão.
<avatar-lib :name = 'myName'></avatar-lib>
Também seria possível organizar eventos de saída.
Demonstração do Vue:
https://github.com/Jamaks/angular-element/tree/master/ang-el-vueÉ hora de reagir! Tudo é tão simples:
<avatar-lib name = {this.myName}></avatar-lib>
Demonstração ao reagirBem, em geral, o projetoQuanto ao suporte ao navegador no momento:
https://angular.io/guide/elements#browser-support-for-custom-elementshttps://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/defineObviamente, você decide se deve usar esse método de implementação. Eu gostaria que os componentes da interface do usuário não fossem anexados a nada e não tivessem sufixos semelhantes: ng-, ngx-, v-, react-, rc- e assim por diante.
Bônus!Inspirado no tamanho do componente (ngx-avatar), ainda tentei alimentar o ngtsc, ngcc e montá-lo usando o rollup. Mas as tentativas foram malsucedidas, pois o componente selecionado exigia muitos módulos externos. Desesperado, parecia um pouco desse componente e os resultados me surpreenderam agradavelmente - no momento (7.1.2), a biblioteca tinha ~ 96kb e ~ 26kb no gzip. Naturalmente, havia muitas dependências e minha configuração de rollup deixa muito a desejar. Mas ainda assim, este não é o 3kb que nos foi mostrado durante a apresentação de Ivy. Resta esperar quando eles implantam o ngcc no Webpack (cli) e escrevem a documentação.
Você também pode
encontrar pequenas experiências e especialistas do mundo angular
aqui .