
Wenn Projekte etwas mehr als eins werden, müssen nicht nur einzelne Module mit Code, sondern auch die UI-Komponenten selbst irgendwie wiederverwendet werden. Es gibt viele Möglichkeiten, das Problem zu lösen - vom herkömmlichen Kopieren und Einfügen bis zum Einrichten eines separaten Projekts mit Tests, Dokumentation und sogar Blackjack.
Das Problem ist, dass die zweite Option einen erheblichen Vorbereitungsaufwand erfordert und jedes dieser Projekte einzigartig ist - mit eigenen Tools, mit denen sich jeder neue Entwickler erneut befassen muss. Ende Juli schlug das Angular-Team eine eigene, umfassende Lösung für dieses Problem vor, indem es angular / cli einen neuen Befehl zum Erstellen von Bibliotheken hinzufügte - Bibliothek.
Mal sehen, was daraus wurde.
Für Tests wurde die neueste stabile Version von Angular / Cli verwendet - 6.1.5 (09/04/2018)
Perfekte Welt
In einer idealen Welt sollte alles bequem sein. Für die Komponentenbibliothek möchte ich drei wichtige Punkte hervorheben
- Einheitlichkeit der Projekte und schneller Start
- Entwicklungskomfort
- Einfache Verteilung
Beginnen wir also von vorne.
Um eine eigene Bibliothek zu erstellen, müssen Sie zwei Schritte ausführen: Erstellen Sie ein neues Projekt und fügen Sie eine Bibliothek hinzu. Erstellen Sie zunächst ein neues Projekt:
npx @angular/cli@latest new mylibapp
npxIch benutze npx, um cli nicht global zu installieren und npm run-Konstrukte zu vermeiden. Wenn Sie npm Version 5.2 oder höher haben, versuchen Sie es. Lesen Sie hier mehr
Nach dem Ausführen des Befehls sehen wir ein Standardprojekt (für 6 Winkel, das sich von der 5. Version unterscheidet), in dem zwei Unterprojekte erstellt werden - das Haupt-Mylibapp und das Mylibapp-e2e. Das Winkelprojekt selbst wird nun in angle.json beschrieben.

Es gibt noch keine Bibliotheken.
Und hier ist er die erste Einschränkung. Unser Name wird bereits vom Hauptprojekt übernommen, und die Bibliothek zu benennen funktioniert auch nicht. Wenn Sie die Bibliothek my-super-library benennen möchten, müssen Sie daher zuerst ein Projekt erstellen, das irgendwie anders aufgerufen werden sollte. Zum Beispiel my-super-library-project. Und erst dann erstellen Sie eine Bibliothek mit dem gewünschten Namen.
Erstellen Sie nun ein drittes Unterprojekt und generieren Sie eine Bibliothek.
cd mylibapp npx ng generate library mylib
Es ist nicht erforderlich, ein Präfix anzugeben, aber es ist sehr wünschenswert, sich nicht mit anderen Bibliotheken zu überschneiden.

Wie Sie sehen, wurde unsere dritte Bibliothek jetzt als drittes Unterprojekt hinzugefügt. Es hat seine eigenen separaten package.json, tsconfig und karma.conf.js, mit denen Sie es konfigurieren können, ohne befürchten zu müssen, andere Projekte zu verletzen. Auf Wunsch können wir übrigens eine weitere Bibliothek hinzufügen, und es wird auch ein separates Teilprojekt sein. Aber deshalb konnte die Bibliothek nicht durch ein völlig separates Projekt unterschieden werden (wie zum Beispiel in .Net), das ich nicht kenne. Und wenn es nicht schwierig ist, das e2e-Projekt von Hand zu entfernen, ist das Hauptprojekt nicht mehr vorhanden. Infolgedessen wird zusätzlicher Code im Repository angezeigt, was nicht sehr gut ist.
Nun wollen wir sehen, welche Werkzeuge wir sofort bekommen. Dies ist ein Haufen Tslint + Codelyzer, Karma + Jasmin und Winkelmesser für e2e. Das heißt, Standard-Winkelprojekt, nichts Spezielles für die Bibliothek, die wir nicht mitgebracht haben. Dies ist etwas seltsam, da einige Tools zum Anzeigen und Rendern von Komponenten (wie ein Storybook ) einfach ein Muss sind. Aber in Ordnung, wir gehen davon aus, dass sie uns hier einfach Spielraum gelassen haben.
Lassen Sie uns die Tests und den Linter ausführen, um sicherzustellen, dass alles funktioniert.
npm test mylib npx ng lint mylib
Für mich lief alles gut, aber Chrome wurde zum Testen verwendet, was auch seltsam ist. Ich habe nichts gegen ihn, aber auf Build-Servern werden es nicht 90% sein. Warum sie nicht denselben Puppenspieler benutzten, ist nicht klar.
Zusammenfassend:
Vorteile
- Schneller Start eines neuen Projekts
- Einheitlicher Ansatz
Nachteile
- Zusätzlicher Code im Projekt
- Offensichtliche Dinge müssen mit Ihren Händen erledigt werden.
Bisher nichts Kritisches, wir graben weiter.
Entwicklung
Wir haben bereits einige der Komponenten im Lieferumfang enthalten. Schauen wir sie uns an. Da wir keine speziellen Werkzeuge haben, werden wir das Hauptprojekt verwenden (hier stellt sich heraus, warum es benötigt wird). Dazu müssen wir die Bibliothek erstellen, das Bibliotheksmodul importieren und das Hauptprojekt starten.
etwas Code npx ng build mylib
import { MylibModule } from "mylib"; ... @NgModule({ declarations: [ AppComponent, ], imports: [ BrowserModule, MylibModule ], providers: [], bootstrap: [AppComponent] })
npm start
Nachdem alles erledigt ist, sehen wir unsere Komponente aus der Bibliothek. Aber auch hier gibt es eine Nuance: Der Überwachungsmodus für die Bibliothek wurde noch nicht ausgeführt. Müssen Sie den Bibliotheksaufbau jedes Mal selbst ausführen? Die Uhr erscheint nur in Angular / CLI 6.2+. Und nicht sofort, dafür müssen Sie in tsconfig.json ein neues Flag hinzufügen
tsconfig.json
"angularCompilerOptions": { "enableResourceInlining": true, }
Führen Sie dann den Build mit der Überwachungsflagge aus:
ng build mylib
Wenn Sie aus irgendeinem Grund cli unter 6.2 verwenden, müssen Sie es selbst erstellen, was ehrlich gesagt schlecht ist.
Fügen wir nun eine neue Komponente hinzu. Führen Sie dazu den Standardbefehl generate component aus. Da die Bibliothek nicht unser Hauptprojekt ist, müssen Sie das Projektflag verwenden, was ebenfalls etwas ärgerlich ist (aber wenn die Bibliothek eine unabhängige Lösung war ...).
npx ng generate component some-nice-image
Erstellen Sie nun unter mylib / src den Assets-Ordner, fügen Sie ein Bild hinzu und erstellen Sie die Bibliothek erneut, um das Ergebnis anzuzeigen. Und dann erwartet uns eine weitere Überraschung - es gibt kein Bild. Es stellt sich heraus, dass die in der Bibliothek verwendeten Ressourcen nicht automatisch in den Build aufgenommen werden. Sie müssen sie selbst kopieren (oder so ). Und es scheint nicht beängstigend zu sein, aber irgendwie nicht richtig.
Aber das Schütteln von Bäumen sollte sofort funktionieren. Lassen Sie uns eine weitere Komponente in der Bibliothek erstellen, diese jedoch nicht im Hauptprojekt verwenden. Zusammenstellen des Hauptprojekts im Produktionsmodus
npx build
Und wir sehen, dass sich die Größe des Bundles nicht geändert hat. Baumschütteln funktioniert wirklich mit Bibliotheken!
Jetzt wäre es schön zu versuchen, eine Art Sucht zu machen. Da jedes Projekt eine eigene package.json hat, müssen wir zuerst in den Bibliotheksordner gehen und den Befehl npm install ausführen
npm i -D @drag13/when-do npm i @drag13/round-to
Ich habe sie absichtlich auf verschiedene Arten platziert, um zu überprüfen, wie der Packer später damit umgehen würde. Alles ist ohne Probleme eingestellt. Wir versuchen zu sammeln und eine Warnung zu bekommen
Das Verteilen von npm-Paketen mit 'Abhängigkeiten' wird nicht empfohlen. Bitte ziehen Sie in Betracht, drag13 / round-to zu 'peerDependencies' hinzuzufügen oder es aus 'abhängigkeiten' zu entfernen
Das Verteilen von npm-Abhängigkeitspaketen ist nicht wünschenswert. Bitte erwägen Sie, PeerDependencies Drag13 / Round-to-Abhängigkeiten hinzuzufügen oder sie sogar aus Abhängigkeiten zu entfernen
und dann der Fehler:
Die Abhängigkeit drag13 / round-to muss explizit in die Whitelist aufgenommen werden
Die Abhängigkeit drag13 / round-to muss explizit zur Whitelist hinzugefügt werden.
Dies ist bereits interessant, da die Bibliothek keine direkten Abhängigkeiten haben möchte. Wir versuchen, unsere Sucht in den Bereich peerDependencies zu verlagern und wieder zusammenzusetzen - voila, alles funktioniert. Dies bedeutet jedoch, dass die Installationsreihenfolge von Bibliotheken von Drittanbietern jetzt anders ist. Legen Sie zuerst die Abhängigkeit vom Hauptmodul ab und fügen Sie die Stifte dann mit Stiften zum Abschnitt peerDependencies der Bibliothek hinzu.
Der Rest funktioniert genauso wie in einem regulären Angular-Projekt.
Kurz zusammengefasst:
Vorteile:
- Wir arbeiten in einer vertrauten Umgebung mit vertrauten Teams
- Es wird aus dem Kasten geschüttelt
Nachteile:
- Um die Komponente zu sehen, müssen Sie das gesamte Projekt verwenden
- Es gibt noch keinen Überwachungsmodus
- Ressourcen müssen manuell kopiert oder der Erstellungsprozess selbst konfiguriert werden.
Und zum Schluss gehen Sie zur Veröffentlichung
Posting
Hier stimmt alles. Angular / cli verwendet das etablierte ng-packgr zum Veröffentlichen, das unseren Code unabhängig in ein Paket kompiliert , das für die Veröffentlichung von npm geeignet ist, wobei die Dateieinstellung package.json (die nicht klein ist), die Minimierung und das Packen in verschiedenen Formaten (z. B. in UMD) weggelassen werden. .
Um Ihr Paket zu veröffentlichen (oder zu sehen, was darin enthalten ist), müssen Sie drei Befehle ausführen
npx ng build
Wenn Sie nicht veröffentlichen möchten, ersetzen Sie den Veröffentlichungsbefehl durch pack
Als Ergebnis habe ich Folgendes erhalten:

Schauen wir uns zunächst package.json an, das ganz anders aussieht als das ursprüngliche package.json unserer Bibliothek.

Wie Sie sehen können, hat packagr unsere devDependencies nicht gelöscht, obwohl einige dies tun. Darüber hinaus theoretisch zufrieden mit der Anzahl der Formate, die in package.json beschrieben sind (obwohl ich die Hälfte davon nicht kenne).
Das Paket enthält ein minimiertes und ein nicht minimiertes Bundle im UMD-Format sowie mehrere weitere Bundles im internen Winkelformat (fesm5, fesm2015). Vor allem aber wird der Kopf der Entwickler jetzt nicht mehr schaden, was einfach wunderbar ist.
Kommen wir zu den Schlussfolgerungen.
Vorteile:
- Bequemlichkeit
- Nachdenklichkeit
Insgesamt
Die Lösung war interessant, aber roh. Der Start und die Veröffentlichung sind sehr bequem, aber es gibt noch Fragen zur Entwicklung. Es ist besonders frustrierend, dass die Bibliothek jetzt kein eigenständiges Projekt ist, sondern eine Ergänzung des Hauptprojekts mit der Möglichkeit der Veröffentlichung.
Auf der anderen Seite wurde ein großer Teil der Arbeit erledigt, die Funktionalität wird ständig weiterentwickelt, und ich bin sicher, dass wir im Laufe der Zeit ein hervorragendes Werkzeug für die Entwicklung erhalten werden.