Beginnen Sie von vorne
Wenn der Speicher mir recht tut, wurde es ab Version 6 im Winkel möglich, verschiedene Arten von Projekten in einem Arbeitsbereich zu erstellen: Anwendung und Bibliothek.
Bis zu diesem Zeitpunkt verwendeten Personen, die eine Komponentenbibliothek erstellen wollten, höchstwahrscheinlich das ausgezeichnete und nützliche ng-packagr-Paket, mit dessen Hilfe das Paket in dem für Angular akzeptierten Format erstellt werden konnte. Eigentlich habe ich die vorherige Bibliothek mit diesem Tool erstellt. Jetzt hat das Angular-Team ng-packagr in angle-cli aufgenommen und Schaltpläne zum Erstellen und Erstellen von Bibliotheken hinzugefügt, das Angular.json-Format erweitert und einige weitere Annehmlichkeiten hinzugefügt. Gehen wir jetzt von ng new zu npm install über - von der Erstellung einer leeren Bibliothek über die Veröffentlichung bis hin zum Import in ein Drittanbieterprojekt.
Der Arbeitsbereich wird wie gewohnt erstellt
ng new test-app
Arbeitsbereich und Anwendungsprojekt werden erstellt. Schauen Sie sich angle.json an
{ ... "projects": { "test-app": { ... "sourceRoot": "src", "projectType": "application", "prefix": "app" ... } ... } ... }
Fügen Sie nun das Bibliotheksprojekt hinzu
ng generate library test-lib --prefix=tl
Wir werden den Schlüssel --prefix hinzufügen, um anzuzeigen, dass die Komponenten und Anweisungen das Präfix tl verwenden, dh die Komponenten-Tags sehen aus
<tl-component-name></tl-component-name>
Mal sehen, in angular.json haben wir ein neues Projekt hinzugefügt
{ ... "projects": { "test-app": { "root": "", "sourceRoot": "src", "projectType": "application", "prefix": "app" ... }, ... "test-lib": { "root": "projects/test-lib", "sourceRoot": "projects/test-lib/src", "projectType": "library", "prefix": "tl" } ... } ... }
Die folgende Struktur wurde im Projektverzeichnis angezeigt
- projects - test-lib ng-package.json package.json - src public-api.ts - lib test-lib.component.ts test-lib.module.ts test-lib.service.ts
In tsconfig.json gibt es außerdem einen Zusatz im Abschnitt "Pfade"
"paths": { "test-lib": [ "dist/test-lib" ], "test-lib/*": [ "dist/test-lib/*" ] }
Wenn Sie nun die Anwendung ausführen,
ng serve
Dann sehen wir eine Standardvorlage für funktionierende Winkelanwendungen
Bibliotheksfunktionalität erstellen
Erstellen wir eine Bibliothek mit einem Dienst, einer Direktive und einer Komponente. Wir werden den Dienst und die Richtlinie in verschiedene Module einteilen. Wechseln wir in das Verzeichnis projects / test-lib / src / lib und löschen Sie test-lib. *. Ts. Löschen Sie auch den Inhalt von projects / test-lib / src / public-api.ts.
Wechseln wir zu Projekten / test-lib / src / lib und erstellen Module, Direktiven, Dienste und Komponenten
ng g module list ng g module border ng g service list /* list*/ ng g component list /* border*/ ng g directive border
Füllen Sie die Komponente, den Dienst und die Direktive mit Logik. Die Komponente zeigt eine Liste der an die Eingabe gesendeten Zeilen an. Die Anweisung besteht darin, einen roten Rahmen hinzuzufügen. Der Dienst fügt jede Sekunde den aktuellen Zeitstempel zum Observable hinzu.
Service
import {Injectable} from '@angular/core'; import {Observable, Subject} from 'rxjs'; @Injectable({ providedIn: 'root' }) export class ListService { timer: any; private list$: Subject<string> = new Subject<string>(); list: Observable<string> = this.list$.asObservable(); constructor() { this.timer = setInterval(this.nextItem.bind(this), 1000); } nextItem() { const now = new Date(); const currentTime = now.getTime().toString(); this.list$.next(currentTime); } }
Komponentenliste und Modul
import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {ListComponent} from './list/list.component'; @NgModule({ declarations: [ ListComponent ], exports: [ ListComponent ], imports: [ CommonModule ] }) export class ListModule { } @Component({ selector: 'tl-list', template: ` <ul> <li *ngFor="let item of list">{{item}}</li> </ul>`, styleUrls: ['./list.component.css'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ListComponent implements OnInit { @Input() list: string[]; constructor() { } ngOnInit() { } }
Rahmen
import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {BorderDirective} from './border.directive'; @NgModule({ declarations: [ BorderDirective ], exports: [ BorderDirective ], imports: [ CommonModule ] }) export class BorderModule { } import {Directive, ElementRef, OnInit} from '@angular/core'; @Directive({ selector: '[tlBorder]' }) export class BorderDirective implements OnInit { private element$: HTMLElement; constructor(private elementRef$: ElementRef) { this.element$ = elementRef$.nativeElement; } ngOnInit() { this.element$.style.border = 'solid 1px red'; } }
! Es ist wichtig. Beim Generieren von Komponenten und Bibliotheken erstellt cli keinen Export. Fügen Sie daher unbedingt die Komponenten und Anweisungen hinzu, die im Exportabschnitt in den Modulen verfügbar sein sollten.
Damit in Zukunft Klassen aus der Bibliothek verfügbar sind, werden wir public-api.ts Code hinzufügen
export * from './lib/list.service'; export * from './lib/border/border.module'; export * from './lib/border/border.directive'; export * from './lib/list/list.module'; export * from './lib/list/list/list.component';
Verbinden einer Bibliothek in einer Testanwendung
Lassen Sie uns das Bibliotheksprojekt zusammenstellen
ng build test-lib --watch
Als nächstes importieren wir in app.module die Module mit der Komponente und der Direktive und fügen die Logik hinzu
import {BrowserModule} from '@angular/platform-browser'; import {NgModule} from '@angular/core'; import {AppRoutingModule} from './app-routing.module'; import {AppComponent} from './app.component'; import {ListModule} from 'test-lib'; import {BorderModule} from 'test-lib'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, ListModule, BorderModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Und verwenden Sie die Stücke aus unserer Bibliothek in der Anwendung
import {Component, OnInit} from '@angular/core'; import {ListService} from 'test-lib'; @Component({ selector: 'app-root', template: ` <tl-list [list]="list"></tl-list> <div tlBorder>I am bordered now</div>`, styleUrls: ['./app.component.styl'] }) export class AppComponent implements OnInit { list: string[] = []; constructor(private svc$: ListService) { } ngOnInit() { this.svc$.list.subscribe((value => this.list = [...this.list, value])); } }
Führen Sie die Anwendung aus und überprüfen Sie sie. Alles funktioniert:

Montage und Veröffentlichung
Es bleibt zu sammeln und das Paket zu veröffentlichen. Zum Zusammenstellen und Veröffentlichen ist es praktisch, Skripten in der Anwendung package.json Befehle hinzuzufügen
{ "name": "test-app", "version": "0.0.1", "scripts": { ... "lib:build": "ng build test-lib", "lib:watch": "ng build test-lib --watch", "lib:publish": "npm run lib:build && cd dist/test-lib && npm pack npm publish", ... } }
Die Bibliothek wird jetzt nach der Installation in einem anderen Winkelprojekt zusammengestellt und veröffentlicht
npm install test-lib
Sie können Komponenten und Anweisungen verwenden.
Kleine Notiz
Wir haben eine ganze Familie von npm-Paketen in unserem Unternehmen, daher sollte das Paket in unserem Fall mit dem Namespace als
company / test-lib veröffentlicht werden. Dazu nehmen wir nur wenige Änderungen vor.
Benennen Sie das Paket in der package.json-Bibliothek um
/* projects/test-lib/package.json */ { "name": "@company/test-lib", "version": "0.0.1", "peerDependencies": { "@angular/common": "^7.2.0", "@angular/core": "^7.2.0" } }
Damit in der Testanwendung auf die Bibliothek über den Namen mit dem Namespace zugegriffen werden kann, werden wir tsconfig ein wenig korrigieren
/* test-app/tsconfig.json */ *** "paths": { "@company/test-lib": [ "dist/test-lib" ], "@company/test-lib/*": [ "dist/test-lib/*" ] } ***
Und in der Testanwendung ersetzen Sie beispielsweise die Importe
import {ListModule} from 'test-lib';
Ersetzen durch
import {ListModule} from '@company/test-lib';
Dies ist das Ende.
PS: Als ich dieses Thema studiert habe, habe ich einmal die folgenden Artikel gelesen
Die eckige BibliotheksreiheErstellen einer npm-fähigen Komponentenbibliothek mit Angular