Suche
Die Ruhe vor dem Sturm?

Angular 7: Neuerungen und ein Blick in die Zukunft

Manfred Steyer

© Shutterstock / Sergey Nivens

Angular 7 bringt ein paar nette Abrundungen und Bugfixes. Die meisten Ressourcen fließen derzeit jedoch in den neuen Ivy-Compiler, der nicht nur kleinere Bundles erzeugt, sondern auch mehr Flexibilität bringt. Dieser wird in ein paar Monaten der Allgemeinheit zur Verfügung gestellt.

Gemäß des sich selbst auferlegten halbjährlichen Releasezyklus war es im Oktober 2018 wieder so weit: Das Angular-Team hat ein neues Major Release veröffentlicht. Mittlerweile sind wir bei Version 7. Der Übergang zu dieser Version ist erfrischend geradlinig – der einzige Breaking Change ist, dass man auch das neue TypeScript 3.1 installieren muss. Und selbst diese einfache Migration wurde mit einem Skript automatisiert.

Die neue Version kommt mit ein paar Bugfixes und einer sehr überschaubaren Menge neuer Features. Der Grund für diesen geringen Featurezuwachs ist, dass das Core-Team derzeit alle Ressourcen in den nächsten großen Coup investiert: Der neue Ivy-Compiler, der zum einen für kleinere Bundles sorgt und zum anderen Angular um einiges flexibler gestaltet. Dieser soll in den nächsten Monaten erscheinen und sich über ein Feature-Flag aktivieren lassen.

Dieser Artikel geht auf die wichtigsten Neuerungen von Angular 7 und dem dazugehörigen Angular CLI 7 ein.

Upgrade

Dank des relativ jungen CLI-Befehls update ist die Aktualisierung des Frameworks fast zu einfach um wahr zu sein. Es reicht folgende Anweisung:

ng update @angular/cli @angular/core

Das veranlasst das CLI dazu, die neuesten Pakte zu laden und die package.json zu aktualisieren. Danach sollte sich die Anwendung mit der neuen Angular-Version starten lassen.

Shadow DOM 1.0 und Content Projection

hadow DOM ist einer der Standards, an denen sich Angular von Anfang an orientiert. Die aus der Welt der Web Components stammende Idee ist, einer Komponente eigene Styles zu spendieren, ohne dass sich diese auf andere Komponenten auswirken. Da nicht alle Browser Shadow DOM unterstützen, nutzt das Framework standardmäßig eine Emulation. Die ist in der Regel ganz passabel, kann aber nicht den vollen Umfang einer browserbasierten Implementierung bieten.

angular-7-steyer-1

Abb. 1: Web Component mit Shadow DOM 1 und Content Projection

Um letztere zu aktivieren, ist die Eigenschaft encapsulation im Component-Dekorator auf ViewEncapsulation.Native zu setzen. Allerdings nutzt diese Option lediglich die sogenannte Version 0 von Shadow DOM. Die Browserhersteller haben sich mittlerweile auf eine Version 1 geeinigt und implementieren sie mittlerweile auf breiter Basis.

Diese lässt sich seit der Angular-Version 6.1 mit der Eigenschaft ViewEncapsulation.ShadowDom aktivieren. Neu ist nun mit Version 7 jedoch, dass Angular im Zusammenspiel mit Shadow DOM 1 auch Content Projection erlaubt. Das bedeutet, dass die Komponente beim Aufruf HTML-Fragmente entgegennimmt und diese an bestimmten Stellen in ihrem Template platziert.

Zur Veranschaulichung dieser Möglichkeit verwende ich hier die Komponente in Abbildung 1.

Während die Komponente die drei Werte für das Diagramm über ein Property Binding entgegennimmt, schleust der Aufrufer die Überschrift sowie die Texte am Ende über Content Projection ein. Im Kontext von Shadow DOM 1 (Listing 1) kann das Template der Komponente mit den neuen slot-Elementen darauf verweisen (Listing 2).

@Component({
  selector: 'app-dashboard-tile',
  templateUrl: './dashboard-tile.component.html',
  encapsulation: ViewEncapsulation.ShadowDom
})
export class DashboardTileComponent implements OnInit {
  @Input() a: number;
  @Input() b: number;
  @Input() c: number;
  […]
}

Standardwert

Standardwert

Standardwert

Diese Slots sind lediglich Platzhalter für das übergebene HTML Markup und können einen Standardwert beinhalten. Außerdem darf das Template mehrere Slots definieren. Darunter kann es einen Standardslot und beliebige viele weitere Slots geben. Letztere müssen einen Namen über das name-Attribut erhalten.

Der Aufrufer übergibt in weiterer Folge beliebiges Markup an die Komponente. Das Attribut slot weist die einzelnen Elemente jeweils einem Slot zu (Listing 3). Alles, was auf diese Weise nicht explizit einem Slot zugeordnet wird, kommt in den Standardslot.

Important Stuff A, B and C show the values of A, B and C. Only believe in statistics you've faked yourself.

Prompts für Codegenerierung

Seit einiger Zeit erleichtert das Angular CLI mit sogenannten Schematics die Generierung von wiederkehrendem Code. Dieser Codegenerator erzeugt zum Beispiel beim Aufruf von ng new das Grundgerüst einer neuen Anwendung oder beim Aufruf von ng generate u a. neue Komponenten, Services oder Module.

Um Details der Codegenerierung zu bestimmen, nehmen diese Anweisungen eine ganze Menge an Parametern entgegen. Das kann schon ermüdend sein. Deswegen bietet Schematics nun die Möglichkeit, interaktiv Informationen einzuholen (Abb. 2).

angular-7-steyer-2

Abb. 2: Das CLI kann nun interaktiv Informationen einholen

Hinter diesem einfach wirkenden Mechanismus steckt ein durchdachtes Programmdesign. Die Art der Informationseinholung kann beispielsweise durch Festlegen eines PromptProviders ausgetauscht werden und sämtliche eingeholten Informationen werden über Metadaten beschrieben.

Wer seinen eigenen Codegenerator mit Schematics bereitstellen möchte, muss lediglich ein JSON-Schema mit den gewünschten Parametern bereitstellen. Parameter, die über die Konsole zu erfragen sind, erhalten die Eigenschaft x-prompt.

Listing 4 veranschaulicht dies anhand eines Schematics, der mit einer nicht ganz ernst zu nehmenden Logik Produktnamen generiert.

{
  "$schema": "http://json-schema.org/schema",
  "id": "AwesomeProductNameSchematic",
  "title": "Schematic for Product Names",
  "type": "object",
  "properties": {
    "internalName": {
      "type": "string",
      "description": "The short and boring internal name",
      "x-prompt": "What is the short and boring internal name?"
    },
    "coolness": {
      "type": "number",
      "description": "Degree of coolness",
      "default": 2,
      "x-prompt": {
        "type": "list",
        "message": "How cool shall the new name be?",
        "items": [
          […]
          {
            "value": 2,
            "label": "Very cool"
          },
          […]
        ]
      }
    }
  }
}

Die Eigenschaft x-prompt kommt hier zunächst in ihrer Kurzform zum Einsatz. Diese sieht vor, dass sie lediglich die zu stellende Frage beinhaltet. Die danach genutzte Langform bietet eine etwas genauere Steuerung der Benutzerinteraktion und kann eine Liste mit möglichen Optionen vorgeben.

Mit Budgets auf die Linie achten

Eins der Hauptziele von Angular ist Performance. Diesem Architekturziel wird auf verschiedene Weise Rechnung getragen. Eine recht junge Maßnahme ist das Definieren von Budgets für die Größe von Bundles. Dazu hinterlegt das Projektteam in der Datei angular.json Größenlimits für die generierten Bundles. Überschreitet es diese, kommt es je nach Einstellung beim Build zu Warnungen oder gar Fehlern.

Das CLI 7 greift diese Möglichkeit auf und konfiguriert standardmäßig ein Budget für das Bundle, das initial geladen wird:

"budgets": [
  {
    "type": "initial",
    "maximumWarning": "2mb",
    "maximumError": "5mb"
  }
]

Ab einer Größe von 2 Megabyte kommt es demnach zu einer Warnung; ab 5 Megabyte zu einem Fehler. Als Alternative zu initial legt die Einstellung all ein Budget für die Gesamtgröße der Anwendung und any für die Größe jeder einzelnen Datei fest. Außerdem hinterlegt die Option bundle ein Budget für ein ganz spezifisches Bundle:

budgets: [
  {
    "type": "bundle",
    "name": "vendor",
    "minimumWarning": "300kb",
    "minimumError": "400kb",
  }
]

Überschreitet man die Budgets, bietet sich ein Blick auf die importierten Bibliotheken an. Der via npm verfügbare Webpack Bundle Analyzer zeigt die Verteilung der einzelnen Libraries auf graphische Weise an und erlaubt somit das Aufspüren der Verursacher. Um ihn zu nutzen, ist zunächst ein Build mit dem Schalter statsJson zu erzeugen. Dieser kümmert sich um das Bereitstellen von Statistiken über den Inhalt der Bundles:

ng build --prod --statsJson

Im dist-Ordner kann danach der Webpack Bundle Analyzer gestartet werden. Er nimmt den Namen der Statistikdatei, die das CLI stats.json nennt, entgegen:

webpack-bundle-analyzer stats.json

Das Ergebnis gestaltet sich dann wie in Abbildung 3.

angular-7-steyer-3

Abb. 3: Der Webpack Bundle Analyzer informiert über den Bundle-Inhalt

Entdeckt man auf diese Weise, dass ein npm-Paket das Problem verursacht, muss nicht gleich seine Berechtigung infrage gestellt werden. Oft gibt es mehrere Optionen zum Referenzieren des Pakets und hier gilt es, eine speichersparende Variante zu finden. Ein Blick in die Doku kann hier Auskunft geben. Entdeckt man hingegen, dass der eigene Programmcode zu groß ist, bietet sich der Einsatz von Lazy Loading an.

Ausblick auf ngIvy

Wie schon eingangs erwähnt, fließen derzeit die meisten Ressourcen des Angular-Teams in den neuen Ivy-Compiler. Dieser stellt die größte interne Änderung seit der Veröffentlichung des Frameworks vor etwas mehr als zwei Jahren dar. Die Idee ist, den Unterbau von Angular auf neue Beine zu stellen, Bundles sollen dadurch merkbar kleiner werden. Ivy erreicht dieses Ziel, indem es Angular-Code in Code, der Tree Shaking unterstützt, beim Build umgewandelt wird. Somit können die nicht benötigten Bestandteile von Angular noch besser entfernt werden.

Das führt dazu, dass UI-Komponenten in sehr DOM-nahen Code umgewandelt werden und danach fast ohne Angular auskommen. Das ist auch für Web Components bzw. Custom Elements essenZiell, denn hier möchte man nicht mit jeder wiederverwendbareN Komponente das gesamte Framework ausliefern. Erste Zahlen sind auch schon vielversprechend. Eine auf Angular basierende Hallo-Welt-Anwendung lässt sich damit auf unter 3 KB reduzieren, wenn man neben den neuen Optimierungen auch auf Komprimierung setzt.

Dem Angular-Team ist es ein besonderes Anliegen, den Wechsel zu Ivy ohne Breaking Changes zu ermöglichen. Deswegen lässt man sich hier lieber etwas länger Zeit. Derzeit wird es bei Google in einigen der mehreren Hundert Angular-Projekten erprobt. Die Allgemeinheit soll Ivy in den nächsten Monaten erhalten und über ein Feature-Flag aktivieren können.

For free: The iJS React Cheat Sheet

For free: The iJS React Cheat Sheet

You want to get started with React? Our Cheat Sheet includes all the most important snippets. Get the sheet for free!

 

API Summit 2018
Christian Schwendtner

GraphQL – A query language for your API

mit Christian Schwendtner (PROGRAMMIERFABRIK)

Ausblick auf Bazel

Während das CLI derzeit auf dem populären Build-Werkzeug webpack basiert, arbeitet das CLI-Team derzeit auch an einer Bazel-integration. Dabei handelt es sich um die Open-Source-Variante der bei Google eingesetzten Build-Lösung. Ihre Stärke ist das inkrementelle Kompilieren, das bedeutet, dass nur die wirklich geänderten Programmteile neu kompiliert werden müssen. Hierdurch erhält man unabhängig von der Projektgröße konstante Build-Zeiten. Das ist gerade bei großen Projekten wichtig und erlaubt, die Auswirkungen einer Programmänderung sofort zu sehen. Außerdem beschränkt sich Bazel nicht nur auf JavaScript-Projekte, sondern kann sich um das Bauen jeder Art von Codebasen, darunter auch serverseitige, kümmern.

Auch wenn sich das verlockend anhört, wird das uns Angular-Team Bazel nicht aufzwingen, sondern es lediglich als Option neben der bisher standardmäßig genutzten webpack-Integration anbieten. Möglich wird das über die mit der CLI 6 eingeführten Builder, die ein Plug-in-System für Build-Aufgaben ermöglichen.

Fazit

Abgesehen von der Notwendigkeit, TypeScript auf Version 3.1 zu aktualisieren, könnte Angular 7 auch als Minor Release durchgehen. Die neuen Features bieten zwar eine nette Abrundung, sind jedoch gleichzeitig auch sehr überschaubar. Das ist jetzt aber nicht schlimm, denn Angular ist mittlerweile ausgereift und die große Community liefert viele zusätzliche Bibliotheken.

Trotzdem arbeitet das Produktteam auf Hochtouren an der nächsten Innovation, die noch mehr an Performance und Flexibilität herausholen soll: Ivy. Dabei handelt es sich um ein anspruchsvolles Unterfangen, dass das Potenzial hat, so manche Bundles um ein Vielfaches schrumpfen zu lassen. Das zeigt auch gleichzeitig wieder einmal, dass das Team bei Google konsequent seine Architekturziele verfolgt und da ist Performance ganz vorne dabei.

Die aktuelle Vorgehensweise zeigt aber auch, dass das Core-Team hinter seinem Versprechen steht, Übergänge zu neuen Major-Versionen einfach zu gestalten. Deswegen wird Ivy erst mal bei Google erprobt und erst dann der Allgemeinheit präsentiert. Wer dann den Feature-Flag für Ivy in seinem Projekt aktiviert, soll zunächst mal keinen Unterschied merken, außer dass die Anwendung dank kleinerer Bundles besser performt.

Geschrieben von
Manfred Steyer
Manfred Steyer
Manfred Steyer ist selbstständiger Trainer und Berater mit Fokus auf Angular 2. In seinem aktuellen Buch "AngularJS: Moderne Webanwendungen und Single Page Applications mit JavaScript" behandelt er die vielen Seiten des populären JavaScript-Frameworks aus der Feder von Google. Web: www.softwarearchitekt.at
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: