Wir implementieren Angular-Komponenten in React, Vue und sogar jQuery, wenn Sie möchten

Wenn Sie in npm eine coole Komponente gefunden haben, die jedoch das Präfix ng, ngx, angle usw. enthält, sollten Sie sich darüber nicht aufregen. Es gibt viele Lösungen, um diese Komponente zu erhalten. In diesem Artikel werden wir eine Lösung betrachten, die offiziell vom Angular-Team unterstützt wird, nämlich Angular Elements.

Wählen Sie zum Üben eine beliebige Komponente aus Awesome Angular .

Ich habe einen einfachen, aber sehr interessanten - ngx-Avatar gewählt . Hier werden wiederum Avatare aus verschiedenen sozialen Netzwerken oder einfach die Initialen des Benutzers angezeigt.
So etwas wie das:


Und er hat eine einfache API, hier ein kleines Beispiel:

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

Erstellen Sie dazu ein Angular-Projekt und verbinden Sie die Bibliothek.

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

Verbinden Sie das Paket mit unserem Modul.

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

Jetzt erstellen wir eine einfache Komponente, da das "AvatarModule" standardmäßig nicht seine einzige Komponente aus exportiert.

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

Der Einfachheit halber haben wir nur einen der Eingabeparameter verwendet.

Wir werden aus all dem eine universelle Komponente schaffen. Damit unsere Elemente funktionieren, müssen Sie unserem Projekt Winkelelemente hinzufügen.

 ng add @angular/elements 

Dieser Befehl enthält unter anderem im Abschnitt "Skripte" eine Lite-Version zum Registrieren von benutzerdefinierten Elementen.

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

Die resultierende app.module.ts:

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

Großartig! Jetzt müssen wir all das Gute sammeln. Erstellen Sie dazu Ihren eigenen Kollektor, der unsere Komponente in eine js-Datei packt:

 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'); })(); 

Alles ist fertig! es bleibt nur zu sammeln. Fügen Sie ein solches Skript zu package.json hinzu.

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

Nun, das ist es! Wir haben eine solche js-Datei `avatar-lib.js` mit einem Gewicht von ~ 221kB und ~ 60kb in gzip. Natürlich sind hier noch viele weitere mit Winkel / Kern enthalten. Der ngx-Avatar selbst wiegt ungefähr 16,8 kB und 5,4 kB in gzip. Um das Gewicht von avatar-lib.js stark zu reduzieren, benötigen wir Ivy Compiler, aber dies ist ein Thema für einen anderen Artikel. (Ich hoffe, dass Ivy in diesem Moment veröffentlicht wird, oder ich sammle manuell von dem, was jetzt verfügbar ist).

Was haben uns Angular Elements gegeben?

Dies ist nur eine praktische API zum Implementieren von Webkomponenten. In der Tat könnte man darauf verzichten. Sehen Sie, was Sie früher tun könnten: ein Artikel von Jia Li (begleitet Zone.js jetzt aktiv) .

Wir binden unsere Komponente in andere Frameworks ein.

Zuerst in Vue. Wir verbinden uns auf jede für Sie bequeme Weise und fügen avatar-lib in die Vorlage ein, übertragen die Daten über Standard-Vue-Bings.

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

Es wäre auch möglich, Ausgabeereignisse zu organisieren.

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

Es ist Zeit zu reagieren! Alles ist genauso einfach:

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

Demo auf Reagieren

Nun, im Allgemeinen das Projekt

Was die Browserunterstützung im Moment betrifft:

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

Natürlich liegt es an Ihnen, zu entscheiden, ob Sie eine solche Implementierungsmethode verwenden. Ich möchte, dass UI-Komponenten an nichts angehängt werden und keine ähnlichen Suffixe haben: ng-, ngx-, v-, react-, rc- und so weiter.

Bonus!

Inspiriert von der Größe der Komponente (ngx-avatar) habe ich immer noch versucht, ngtsc, ngcc zu füttern und sie dann per Rollup zusammenzusetzen. Die Versuche waren jedoch erfolglos, da für die ausgewählte Komponente viele externe Module erforderlich waren. Verzweifelt, machte einen Anschein von dieser Komponente, und die Ergebnisse überraschten mich angenehm - im Moment (7.1.2) war die Bibliothek ~ 96kb und ~ 26kb in gzip. Natürlich gab es viele Abhängigkeiten, und meine Rollup-Konfiguration lässt zu wünschen übrig. Dies sind jedoch nicht die 3 KB, die uns während der Präsentation von Ivy gezeigt wurden. Es bleibt zu erwarten, wenn ngcc in Webpack (cli) bereitgestellt und Dokumentation geschrieben wird.

Hier finden Sie auch kleine Experimente und Insider aus der Angular-Welt.

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


All Articles