So erstellen Sie Ihre eigene Angular-Komponentenbibliothek mit DevUI

So erstellen Sie Ihre eigene Angular-Komponentenbibliothek mit DevUI

Vorwort

Als Front-End-Entwickler werden mit der weiteren Entwicklung und dem Wachstum des Unternehmens immer mehr Anforderungen an die Funktionen und Interaktionen der Komponenten gestellt, und es werden immer mehr gemeinsame Komponenten zwischen verschiedenen Produkten oder Teams vorhanden sein. Zu diesem Zeitpunkt benötigen Sie eine Reihe von Komponentenbibliotheken, um die interne Verwendung zu unterstützen, oder Sie können einige native Bibliotheken von Drittanbietern basierend auf vorhandenen Komponenten erweitern oder kapseln. Dieser Artikel zeigt Ihnen Schritt für Schritt, wie Sie Ihre eigene Angular-Komponentenbibliothek erstellen.

Erstellen einer Komponentenbibliothek

Wir erstellen zunächst ein Angular-Projekt, um die Anzeige und Freigabe von Komponenten zu verwalten. Verwenden Sie den folgenden Befehl, um ein neues Projekt zu generieren

ng new <mein-Projekt>

Nachdem das Projekt initialisiert wurde, rufen Sie das Projekt auf und führen Sie den folgenden CLI-Befehl aus, um das Lib-Verzeichnis und die Konfiguration zu initialisieren und ein Komponentenbibliotheksgerüst zu generieren.

ng generate library <meine-lib> --prefix <mein-prefix>

my-lib ist der für Sie angegebene Bibliotheksname, z. B. devui, my-prefix ist das Komponenten- und Befehlspräfix, z. B. d-xxx, und die standardmäßig generierte Verzeichnisstruktur lautet wie folgt

In der Konfigurationsdatei angular.json kann man zudem erkennen, dass unter Projekte eine weitere Konfiguration für die Projekttypbibliothek vorhanden ist.

"meine-Bibliothek": {
  "Projekttyp": "Bibliothek",
  "root": "Projekte/meine-Bibliothek",
  "sourceRoot": "Projekte/meine-Bibliothek/src",
  "Präfix": "dev",
  "Architekt": {
    "bauen": {
      "Builder": "@angular-devkit/build-ng-packagr:Build",
      "Optionen": {
          "tsConfig": "Projekte/meine-Bibliothek/tsconfig.lib.json",
          "Projekt": "Projekte/meine-Bibliothek/ng-Paket.json"
      },
  "Konfigurationen": {
    "Produktion": {
      "tsConfig": "Projekte/meine-Bibliothek/tsconfig.lib.prod.json"
    }
  }
},
...

Wichtige Konfigurationsänderungen

Anpassung des Verzeichnislayouts

Anhand der Verzeichnisstruktur können wir erkennen, dass die standardmäßig generierte Verzeichnisstruktur relativ tief ist. In Bezug auf Materialdesign passen wir die Verzeichnisstruktur wie folgt an:

Änderungshinweise:

  • Löschen Sie das src-Verzeichnis unter dem my-lib-Verzeichnis, kopieren Sie test.ts aus dem src-Verzeichnis und verwenden Sie es als Einstiegspunkt für die Testdatei der Komponentenbibliothek
  • Reduzieren Sie die Komponenten in das Verzeichnis my-lib und fügen Sie my-lib.module.ts (zum Verwalten des Imports und Exports von Komponenten) und index.ts (exportieren Sie my-lib.module.ts, um den Import zu vereinfachen) im Verzeichnis my-lib hinzu.
  • Ändern Sie den SourceRoot-Pfad unter my-lib in angular.json, sodass er auf my-lib verweist.

Ändern Sie wie folgt:

// meine-lib.module.ts


importiere { NgModule } von '@angular/core';
importiere { CommonModule } von '@angular/common';
importiere { AlertModule } from 'my-lib/alert'; // Importiere hier entsprechend der On-Demand-Importmethode, my-lib entspricht unserem Release-Bibliotheksnamen @NgModule({
  Importe: [Gemeinsames Modul],
  Exporte: [AlertModule],
  Anbieter: [],
})
Exportklasse MyLibModule {}


// index.ts
exportiere * aus './my-lib.module';


//angular.json
"Projekttyp": "Bibliothek",
"root": "Projekte/meine-Bibliothek",
"sourceRoot": "projects/my-lib", // Der Pfad hier zeigt auf unser neues Verzeichnis "prefix": "devui"

Tastenkonfiguration für den Bibliotheksaufbau

ng-package.json Konfigurationsdatei, die Konfigurationsdatei, von der die Angular-Bibliothek beim Erstellen abhängt

{
  "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
  "Ziel": "../../veröffentlichen",
  "Bibliothek": {
    "Eintragsdatei": "./index.ts"
  },
  "auf der Whiteliste aufgeführte Nicht-Peer-Abhängigkeiten": ["lodash-es"]
}

Wichtige Konfigurationsanweisungen:

  • dest, Ausgabepfad des Lib-Builds, hier ändern wir ihn in das Veröffentlichungsverzeichnis, getrennt vom Dist-Verzeichnis des Projekt-Builds
  • lib/entryFile, gibt die Eintragsdatei des Bibliotheksaufbaus an, die auf unsere oben stehende index.ts verweist

whitelistedNonPeerDependencies (optional). Wenn die Komponentenbibliothek von einer Drittanbieterbibliothek wie lodash abhängt, müssen Sie hier eine Whitelist konfigurieren. Denn ng-packagr überprüft beim Erstellen die Abhängigkeitskonfiguration von package.json, um das Risiko mehrerer Versionskonflikte in abhängigen Drittanbieterbibliotheken zu vermeiden. Wenn keine Whitelist konfiguriert ist, schlägt der Build fehl, wenn eine Abhängigkeitskonfiguration vorhanden ist.

Für die package.json-Konfiguration wird die Verwendung von peerDependcies empfohlen, wenn das Unternehmen auch verwandte Abhängigkeiten konfiguriert.

{
  "Name": "meine-Bibliothek",
  "version": "0.0.1",
  "Peer-Abhängigkeiten": {
    "@angular/common": "^9.1.6",
    "@angular/core": "^9.1.6",
    "tslib": "^1.10.0"
  }
}

Eine detaillierte und vollständige Konfiguration finden Sie in der offiziellen Angular-Dokumentation https://github.com/ng-packagr/ng-packagr/blob/master/docs/DESIGN.md

Entwickeln einer Alert-Komponente

Einführung in die Komponentenfunktion

Wir beziehen uns auf die Warnkomponente der DevUI-Komponentenbibliothek, um eine Komponente zum Testen unserer Komponentenbibliothek zu entwickeln. Die Warnkomponente zeigt hauptsächlich je nach vom Benutzer übergebenem Typ unterschiedliche Farben und Symbole an und wird verwendet, um dem Benutzer unterschiedliche Warnmeldungen anzuzeigen. Die optische Darstellung erfolgt wie folgt

Zerlegung der Komponentenstruktur

Schauen wir uns zunächst an, welche Dateien das Verzeichnis der Alarmkomponente enthält

Beschreibung der Verzeichnisstruktur:

  • Die Komponente ist ein vollständiges Modul (wie ein normales Business-Modul) und enthält eine Unit-Test-Datei
  • Im Komponentenverzeichnis befindet sich eine Datei package.json zur Unterstützung der sekundären Eingabe (eine einzelne Komponente unterstützt die On-Demand-Einführung).
  • public-api.ts wird zum Exportieren von Modulen, Komponenten, Diensten usw. verwendet. Es ist der externe Expositionseintrittspunkt. index.ts exportiert public-api, um andere Module zu unterstützen

Die wichtigsten Punkte sind:

// paket.json
{
  "ngPackage": {
    "Bibliothek": {
      "Eintragsdatei": "public-api.ts"
    }
  }
}


//öffentliche-api.ts
/*
* Öffentliche API-Oberfläche von Alert
*/
exportiere * aus „./alert.component“;
exportiere * aus './alert.module';

Definieren von Eingabe und Ausgabe

Als Nächstes beginnen wir mit der Implementierung der Komponente. Zuerst definieren wir die Eingabe und Ausgabe der Komponente. Wir übergeben den Alarminhalt per Projektion. Der Eingabeparameter unterstützt die Angabe des Alarmtyps, ob ein Symbol angezeigt werden soll und ob der Alarm geschlossen werden kann. Die Ausgabe gibt einen Close-Callback zurück, damit der Benutzer die Logik nach dem Schließen verarbeiten kann.

importiere { Komponente, Eingabe } von '@angular/core';
// Definieren Sie die optionalen Typen des Warnungsexporttyps AlertType = „Erfolg“ | „Gefahr“ | „Warnung“ | „Info“;


@Komponente({
  Selektor: ‚Entwickleralarm‘,
  Vorlagen-URL: "./alert.component.html",
  styleUrls: ['./alert.component.scss'],
})
Exportklasse AlertComponent {
  // Alarmtyp@Input() Typ: AlertType = 'info';
  // Ob das Symbol angezeigt werden soll, um benutzerdefinierte Symbole zu unterstützen @Input() showIcon = true;
  // Ist es möglich, @Input() zu schließen closeable = false;
  // Rückruf schließen @Output() closeEvent: EventEmitter<boolean> = new EventEmitter<boolean>();
  ausblenden = falsch;
  Konstruktor() {}


  schließen(){
    dies.closeEvent.emit(true);
    dies.hide = wahr;
  }
}

Definieren des Layouts

Gemäß der API-Definition und der visuellen Darstellung implementieren wir die Seitenlayoutstruktur. Das Layout umfasst eine Schließen-Schaltfläche, einen Symbolplatzhalter und eine Inhaltsprojektion. Wenn die Komponente geschlossen wird, löschen wir das DOM.

<div Klasse="dev-alert {{ Typ }} " *ngIf="!hide">
  <button type="button" class="dev-close" (click)="schließen()" *ngIf="schließbar"></button>
  <span class="dev-alert-icon icon-{{ type }}" *ngIf="showIcon"></span>
  <ng-Inhalt></ng-Inhalt>
</div>

An diesem Punkt wurden das Seitenlayout und die Komponentenlogik unserer Komponente gekapselt und die Entwicklung basierend auf der visuellen Anzeige und der entsprechenden Stilverarbeitung abgeschlossen.

Testen der Alarmkomponente

Entwicklungsreferenzkomponenten

Während der Komponentenentwicklung müssen wir in der Lage sein, Logik zu debuggen und die UI-Anzeige in Echtzeit anzupassen. Öffnen Sie tsconfig.json im Stammverzeichnis und ändern Sie die Pfadzuordnung, um das lokale Debuggen unserer Komponenten im Entwicklungsmodus zu erleichtern. Hier wird my-lib direkt auf den Komponentenquellcode verwiesen. Natürlich können Sie auch die Standardkonfiguration über ng build my-lib --watch verwenden, um auf die erstellte Vorabversionsdatei zu verweisen. Zu diesem Zeitpunkt müssen wir es auf das geänderte Verzeichnis public/my-lib/* konfigurieren.

"Pfade": {
  "meine-lib": [
    "Projekte/meine-Bibliothek/index.ts"
  ],
  "meine-lib/*": [
    "Projekte/meine-Bibliothek/*"
  ],
}

Nachdem die Konfiguration abgeschlossen ist, können Sie die Bibliothek, die wir entwickeln, in der Anwendung auf npm-Art verwenden. Wir importieren zuerst die Komponenten, die wir entwickeln, in app.module.ts. Hier können wir alle Komponenten aus my-lib.module importieren oder direkt unser AlertModule importieren (das so konfiguriert wurde, dass es sekundären Zugriff unterstützt).

importiere { AlertModule } aus „my-lib/alert“;
// importiere { MyLibModule } von „my-lib“;


@NgModule({
  Erklärungen: [
    AppComponent
  ],
  Importe: [
    BrowserModule,
    AppRoutingModule,
    // MeinLibModul
    Warnmodul
  ],
  Anbieter: [],
  Bootstrap: [Anwendungskomponente]
})
exportiere Klasse AppModule { }

An diesem Punkt können Sie die Alarmkomponente, die wir entwickeln, direkt auf der Seite app.component.html verwenden.

<Abschnitt>
  <dev-alert>Ich bin ein Standardalarmtyp</dev-alert>
</Abschnitt>

Öffnen Sie die Seite und Sie können die Auswirkungen der aktuellen Entwicklung sehen. Zu diesem Zeitpunkt können wir den Stil und die Interaktionslogik entsprechend der Seitenleistung anpassen. Ich werde es hier nicht weiter zeigen.

Schreiben von Unit-Tests

Wie bereits erwähnt, verfügen wir über eine Unit-Test-Datei. Um die Qualität des Codes und die Stabilität der nachfolgenden umgestalteten Komponenten sicherzustellen, wird empfohlen, bei der Entwicklung von Komponenten Unit-Tests hinzuzufügen.

Da wir die Verzeichnisstruktur angepasst haben, ändern wir zuerst die entsprechende Konfiguration

// angle.json
"meine-Bibliothek": {
  ...
  "prüfen": {
    "Builder": "@angular-devkit/build-angular:karma",
    "Optionen": {
      "main": "projects/my-lib/test.ts", // Dies zeigt auf den angepassten Dateipfad "tsConfig": "projects/my-lib/tsconfig.spec.json",
      "karmaConfig": "Projekte/meine-Bibliothek/karma.conf.js"
    }
  },
}


//tsconfig.spec.json im my-lib-Verzeichnis  


"Dateien": [
  "test.ts" // zeigt auf die Testeintragsdatei im aktuellen Verzeichnis]

Nachfolgend finden Sie eine einfache Testreferenz, die lediglich testet, ob der Typ korrekt ist. Die zu testenden Komponenten sind in der Testdatei definiert. Wenn es viele Szenarien gibt, wird empfohlen, eine Demo bereitzustellen und die Demo direkt zu verwenden, um verschiedene Szenarien zu testen.

importiere { async, ComponentFixture, TestBed } von '@angular/core/testing';


importiere { Komponente } aus '@angular/core';
importiere { AlertModule } aus './alert.module';
importiere { AlertComponent } aus './alert.component';
importiere { Von } von '@angular/platform-browser';


@Komponente({
  Vorlage: `
    <dev-alert [Typ]="Typ" [showIcon]= "showIcon"[schließbar]="schließbar" (closeEvent)="handleClose($event)">
    <span>Ich bin eine Alert-Komponente</span>
    </Entwickleralarm>
  `
})
Klasse TestAlarmComponent {
  Typ = "Info";
  Symbol anzeigen = falsch;
  schließbar = falsch;
  Klickanzahl = 0;
  handleClose(Wert) {
    dies.clickCount++;
  }
}


beschreiben('Alarmkomponente', () => {
  let-Komponente: TestAlertComponent;
  let Vorrichtung: ComponentFixture<TestAlertComponent>;
  let alertElement: HTMLElement;


  vorJedem(async(() => {
    TestBed.configureTestingModule({
      Importe: [AlertModule],
      Deklarationen: [ TestAlertComponent ]
    })
    .compileComponents();
  }));


  vorJedem(() => {
    Vorrichtung = TestBed.createComponent(TestAlertComponent);
    Komponente = Vorrichtung.Komponenteninstanz;
    alertElement = Vorrichtung.debugElement.query(Durch.Direktive(AlertComponent)).nativeElement;
    Vorrichtung.Änderungen erkennen();
  });


  beschreiben('Alarm-Instanztest', () => {
    es('sollte erstellen', () => {
      erwarte(Komponente).toBeTruthy();
    });
  });


  beschreiben('Alarmtyptest', () => {
    it('Alarm sollte Infotyp haben', () => {
      erwarten(alertElement.querySelector('.info')).nicht.toBe(null);
    });


    it('Alarm sollte vom Typ Erfolg sein', () => {
      //Typ ändern, um zu bestimmen, ob die Typänderung korrekt ist. component.type = „success“;
      Vorrichtung.Änderungen erkennen();
      erwarten(alertElement.querySelector('.success')).nicht.toBe(null);
    });
  }

Wir können Unit-Tests ausführen, indem wir ng test my-lib ausführen. Standardmäßig wird ein Fenster geöffnet, das unsere Testergebnisse anzeigt.

An diesem Punkt sind die Referenz und die Tests der Komponentenentwicklung abgeschlossen. Wenn es keine Probleme mit den Funktionen und Interaktionen gibt, können Sie die Veröffentlichung in npm vorbereiten.

Weitere Testinhalte finden Sie in der offiziellen Einführung: https://angular.cn/guide/testing

Release-Komponenten

Nachdem die Komponentenentwicklung abgeschlossen ist und der Komponententest die von uns definierten Zugriffskontrollindikatoren erfüllt, kann er zur Verwendung durch andere Studierende auf npm veröffentlicht werden.

Zuerst erstellen wir die Komponentenbibliothek, da ng9 standardmäßig die Ivy-Engine verwendet. Es wird nicht offiziell empfohlen, Bibliotheken im Ivy-Format im NPM-Repository zu veröffentlichen. Bevor wir es also in NPM veröffentlichen, erstellen wir es mit dem Flag --prod, das den alten Compiler und die alte Laufzeit, die View Engine, anstelle von Ivy verwendet.

ng build meine-lib --prod

Nachdem der Build erfolgreich war, können Sie mit der Veröffentlichung der Komponentenbibliothek beginnen. Hier nehmen wir als Beispiel die Veröffentlichung im offiziellen npm-Repository.

Wenn Sie noch kein npm-Konto haben, gehen Sie bitte auf die offizielle Website, um ein Konto zu registrieren und wählen Sie ein öffentliches kostenloses Konto aus

Wenn Sie bereits ein Konto haben, bestätigen Sie zunächst, dass das konfigurierte Register auf das offizielle npm-Register https://registry.npmjs.org/ verweist.

Führen Sie npm login im Terminal aus, um sich als registrierter Benutzer anzumelden

Nachdem alle Vorbereitungen abgeschlossen sind, gehen Sie zum Build-Verzeichnis, das das Veröffentlichungsverzeichnis ist, und führen Sie dann npm publish --access public aus, um es zu veröffentlichen. Beachten Sie, dass unser Bibliotheksname auf npm leer sein muss. Der Name wird in package.json im Verzeichnis my-lib geändert.

npm-Veröffentlichungsreferenz: https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry

Wenn es sich um eine interne private Bibliothek handelt, konfigurieren Sie die Registrierung einfach entsprechend den Anforderungen der privaten Bibliothek. Die Veröffentlichungsbefehle sind dieselben.

Oben finden Sie Einzelheiten dazu, wie Sie mit DevUI Ihre eigene Angular-Komponentenbibliothek erstellen. Weitere Informationen dazu, wie Sie mit DevUI Ihre eigene Angular-Komponentenbibliothek erstellen, finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Eine kurze Diskussion über versteckte Inhalte in Angular4 ng-content
  • Eine kurze Diskussion über die Angular2 ng-content-Direktive zum Einbetten von Inhalten in Komponenten
  • Detaillierte Erläuterung der Angular-Datenbindung und ihrer Implementierung
  • Detaillierte Erklärung der drei wichtigsten Frontend-Technologien React, Angular und Vue
  • Angular-Leistungsoptimierung: Komponenten von Drittanbietern und Lazy-Loading-Technologie
  • Detaillierte Erklärung der Ansichtszusammenfassungsdefinition im Angular-Framework
  • Detaillierte Erklärung der Rolle von Klammern in AngularJS
  • Detaillierte Erklärung der Angular-Komponentenprojektion

<<:  3 Methoden zum Wiederherstellen der Tabellenstruktur aus einer FRM-Datei in MySQL [empfohlen]

>>:  Detaillierte Erläuterung der MySQL-Installation und der neuen Kennwortauthentifizierungsmethode in MySQL 8.0

Artikel empfehlen

Tutorial zur HTML-Tabellenauszeichnung (9): Zellabstandsattribut CELLSPACING

Damit die Tabelle nicht zu kompakt wirkt, kann zw...

Linux-Systemreparaturmodus (Einzelbenutzermodus)

Inhaltsverzeichnis Vorwort 1. Allgemeine Fehlerbe...

Prozessdiagramm für die Ideenbereitstellung und Tomcat-Dienstimplementierung

Konfigurieren Sie zunächst die Projektartefakte K...

Detaillierte Erklärung von MySQLs Seconds_Behind_Master

Inhaltsverzeichnis Sekunden_hinter_Master Ursprün...

Beispiel, wie man einen Div-Hintergrund transparent macht

Es gibt zwei gängige Möglichkeiten, den Div-Hinte...

Zusammenfassung der Diskussion zur Gültigkeitsdauer von Nginx-Cookies

Bei jedem Besuch wird im Browser Cookie generiert...

Rsync+crontab regelmäßige Synchronisierungssicherung unter centos7

In letzter Zeit möchte ich regelmäßig wichtige in...