So aktualisieren Sie lazy-loaded Angular-Module automatisch für Ivy!

Versuchen Sie Unser Instrument, Um Probleme Zu Beseitigen

So aktualisieren Sie lazy-loaded Angular-Module automatisch für Ivy!

Die unten beschriebene Migration wurde in die Angular-CLI integriert, sodass Sie die von mir erstellte Lint-Regel nicht mehr verwenden müssen. Sie können einfach dem normalen |_+_| folgen Prozess, und Ihr Code wird in das neue Format migriert. Dank anderer Änderungen des Angular-Teams ist es sogar abwärtskompatibel, sodass Sie |_+_| verwenden können ohne Efeu!

Lazy-Loading in Angular vor v8.0.0!

Wenn Sie jemals vor v8.0.0 ein Lazy-Loaded-Modul in einer Angular-App erstellt haben, dann kommt Ihnen der folgende Code vielleicht ziemlich bekannt vor:

|_+_|

Es hat den Job gemacht, aber es war ziemlich magisch, und es stützte sich auf eine spezielle String-Syntax und einige Compiler-Zaubereien im Winkel-CLI



Glücklicherweise haben sich die Webstandards seit der Einführung dieser Syntax weiterentwickelt, und es gibt jetzt eine bessere Möglichkeit, unsere App aufzuteilen und jeden Teil bei Bedarf zu laden!

|_+_|

Dank der Änderungen in Angular 8 können wir jetzt den import()-Operator verwenden, um ein Modul abzurufen, während wir durch unsere Anwendung navigieren.

Die unten beschriebene Migration wurde in die Angular-CLI integriert, sodass Sie die von mir erstellte Lint-Regel nicht mehr verwenden müssen. Sie können einfach dem normalen ng-Aktualisierungsprozess folgen, und Ihr Code wird in das neue Format migriert. Dank anderer Änderungen des Angular-Teams ist es sogar abwärtskompatibel, sodass Sie den Import ohne Ivy verwenden können!

Ich habe den Originalartikel hier als Referenz hinterlassen. Genießen!

Willst du es jetzt? Kühl!

Original:

Wenn Sie bereits mit Ivy spielen, können Sie eine TSLint-Regel mit einem Fixer installieren, um diese automatisch zu aktualisieren:

|_+_|

Fügen Sie Folgendes zu Ihrem |_+_| hinzu:

|_+_|

Und dann ausführen:

|_+_|

Alle Ihre Lazy-Loaded-Routen sollten aktualisiert werden!

Lazy-Loaded-Routen in Angular 7.x.x

Wir gebrauchen |_+_| und |_+_| um Angular über die Routenstruktur unserer Anwendung zu informieren. Aber wie funktioniert es? Schauen wir uns die Angular-Quelle an und finden es heraus!

Wenn wir in die Implementierung von graben |_+_| und |_+_| , können wir sehen, dass, wenn wir das Array von Routen übergeben, sie als Multi-Provider gegen die registriert sind |_+_| |_+_| :

|_+_|

Das bedeutet, dass wir zur Laufzeit ein injizierbares Array von Routenkonfigurationsobjekten haben werden! Aber wie verwendet Angular diese |_+_| ? Schauen wir uns noch einmal die Quelle von Angular (7.x.x) an:

|_+_|

Das |_+_| werden in die Anwendung eingefügt |_+_| wenn es erstellt wird. Wenn Angular auf eine Route mit a trifft |_+_| Eigenschaft darauf, verwendet es die |_+_| zu versuchen und herauszufinden, wie man das lädt. Wir können sehen, dass die |_+_| macht etwas anders basierend auf if |_+_| ist ein |_+_| oder nicht ... tut es aber nicht |_+_| haben eine Schnur sein?

Werfen wir einen Blick auf die Deklaration der |_+_| Typ:

Rasierseiten vs. mvc
|_+_|

Ist das nicht interessant! Sogar in einer Welt vor Ivy, |_+_| kann ein sein |_+_| oder ein |_+_| ! Das sollte also unsere Fantasie bedeuten |_+_| Syntax wird bereits funktionieren?

Was? Es funktioniert! Aber wie geht das?! Warum haben wir die ganze Zeit die Magic-String-Syntax verwendet?!?!

Die Antwort ist es gibt einen Haken …

Lazy-Loaded-Routen in Angular 7.x.x mit Ahead-of-Time-Kompilierung

Wenn wir unsere obige Anwendung nehmen und sie mit dem prod-Flag (|_+_|) erstellen würden, scheint alles zu funktionieren! Aber wenn wir versuchen, zu unserer Lazy-Loaded-Route zu navigieren, erhalten wir einen großen roten Fehler:

Wenn wir unsere App im AOT-Modus ausführen, erhalten wir einen Fehler: Runtime-Compiler ist nicht geladen

Dieser Fehler macht Sinn! Wir haben das |_+_| verwendet Flag, um die Ahead-of-Time zu aktivieren ( AOT )-Compiler, was bedeutet, dass wir den Just-in-time ( JIT ) Runtime-Compiler. Wenn wir uns ansehen, woher der Fehler kommt, können wir sehen, dass er durch den Aufruf von verursacht wurde |_+_| in dem |_+_| :

|_+_|

Wir landen da unten |_+_| Pfad, weil die |_+_| Überprüfung schlägt fehl! Wenn wir die verwenden |_+_| Operator mit AOT ist das Objekt, das wir aus dem Lazy-Loaded-Modul importieren, ein |_+_| anstelle einer |_+_| . Wie stellen wir also sicher, dass wir eine laden |_+_| ?

Von |_+_| zu |_+_| mit dem AOT-Compiler:

Die Aufgabe des Angular-Compilers besteht darin, den gesamten Code in unserer gesamten Anwendung statisch zu analysieren und alle unsere Vorlagen und Stile effizient zu kompilieren. Es dauert unsere |_+_| Dateien und verwandelt sie in |_+_| Dateien, die den generierten Code enthalten, der unsere Ansichten zur Laufzeit erstellt.

Der Compiler kann bei einer bestimmten Datei beginnen und durch alle Importanweisungen navigieren (z. B. |_+_| ) und einen Baum aller referenzierten Module aufbauen. Um unsere Anwendung in Chunks aufzuteilen, müssen wir unseren Code ändern, um diesen Referenzbaum explizit aufzuteilen, und gleichzeitig sicherstellen, dass der Compiler über alle aufgeteilten Teile unserer Anwendung Bescheid weiß. Die Art und Weise, wie wir dies in einer Angular-Anwendung tun, ist mit der |_+_| -Eigenschaft, insbesondere mit dem Magic-String-Format:

|_+_|

Der Angular AOT Compiler findet alle |_+_| durch die Verwendung der |_+_| und sucht dann mit der nach Zeichenfolgen |_+_| Format. Jedes Mal, wenn er eine findet, beginnt der Compiler mit dem angegebenen Pfad, baut den Baum der referenzierten Dateien auf und kompiliert jede |_+_| In ein |_+_| . Wenn wir dieses Format nicht verwenden, landen wir nicht bei der |_+_| die die Laufzeit benötigt. Wenn wir dieses Format verwenden, erhalten wir am Ende eine generierte Datei mit einem unbekannten Pfad, die die |_+_|import()`

Insgesamt bedeutet dies, dass wir zwar mit den Typen in Angular 7.x.x eine asynchrone Funktion für angeben können |_+_| Es wird niemals in einem Produktions-Build unserer Anwendung funktionieren. Aber warum funktioniert die |_+_| Werker arbeiten im JIT-Modus?

Das |_+_| -Operator ist eine weitere Möglichkeit, um zu erklären, dass wir einen anderen Teil unserer Anwendung träge referenzieren möchten. Moderne Tools können dies erkennen, den referenzierten Pfad als weiteren Einstiegspunkt markieren und die Referenz träge zur Laufzeit laden. Leider weiß nur die Angular CLI, wie man a dreht |_+_| In ein |_+_| , und es weiß nichts davon |_+_| . Wir haben gesehen, dass es funktioniert, weil der JIT-Modus nur ein unkompiliertes NgModul benötigt.

Hier sind wir in Angular 7.x.x in eine Art Sackgasse geraten. Damit wir sie nutzen können |_+_| , muss sich etwas an der Funktionsweise von Angular ändern. Zum Glück für uns steht diese Änderung vor der Tür!

Lazy-Loaded-Routen in Angular 8.x.x mit Ivy:

Eines der Hauptdesignziele des neuen Ivy-Renderers ist es, die Unterschiede zwischen dem JIT- und dem AOT-Modus basierend auf dem Lokalitätsprinzip zu beseitigen. Jede Datei weiß alles, was sie wissen muss, ohne zusätzliche Metadatendateien – das bedeutet nicht mehr |_+_| Klassen!

Das bedeutet, dass wir keine separate AOT-Kompilierung mehr ausführen müssen, uns nicht mehr um generierte Dateien mit unbekannten Pfaden kümmern müssen und unsere verwenden können |_+_| Operator!

Upgrade von magischen Zeichenfolgen auf nette asynchrone Funktionen:

Jetzt wissen wir, dass wir ein cooles neues Tool haben, das wir bald verwenden können! Aber wir haben auch eine Menge vorhandenen Codes, der die Magic-String-Syntax verwendet. Wäre es nicht großartig, wenn es eine automatische Möglichkeit gäbe, unseren gesamten alten Code zu aktualisieren?

Python-Regex ersetzt Zeichenfolge

Wir können eine benutzerdefinierte TSLint-Regel und einen Fixer schreiben, um all dies für uns zu erledigen! Schauen wir uns zuerst die ganze Regel an und schlüsseln sie dann auf:

|_+_|

Das Wichtigste zuerst, wir haben einen TSQuery-Selektor, um den Teil des Codes auszuwählen, den wir ändern möchten:

|_+_|

Wir verwenden diesen Selektor in unserer Regel, um uns Zugriff auf die richtigen Teile unseres Codes zu geben:

|_+_|

Wir können die magische Zeichenfolge analysieren und den Ersatzcode erstellen. Der Fixer kann Code generieren, der entweder ein rohes |_+_| verwendet oder |_+_|:

|_+_|

Schließlich müssen wir (etwas ungeschickt) mit Einrückungen im Quellcode umgehen und unseren Fix anwenden:

|_+_|

Und da haben wir es! Ein schöner neuer funkelnder TSLint-Fixer. Wenn mir jemand zeigen/helfen möchte, wie man das in eine ESLint-Regel umwandelt, dann wäre das großartig

Das Ende!

Puh! Wie ist das für einen Brain Dump von bald veraltetem Wissen! Ich hoffe, Sie haben ein oder zwei Dinge gelernt, haben vielleicht ein bisschen weniger Angst davor, den Angular-Quellcode zu lesen, und fühlen sich vielleicht ein bisschen inspiriert, Ihre eigene Automatisierung zum Aktualisieren Ihrer Apps zu schreiben. Bitte kontaktieren Sie mich bei Fragen, und ich würde mich über Ihr Feedback freuen!

Vielen Dank !

Siehe Auch: