© ecco/Shutterstock.com
Neues in der Major-Version

Angular 11: Entwickler im Fokus


Angular hat eine neue Major-Version erhalten, die vor allem den Entwickler von Angular-Projekten adressiert. Enthalten sind einige kleine Neuigkeiten, die aber große Wirkung haben. Auch Breaking Changes gibt es zu vermelden, allerdings hilft hier das CLI weiter.

Am 11.11. erschien Angular in Version 11. Die rund fünf Monate Arbeit seit dem letzten Major Release am 24. Juni und dem Minor Release 10.1 am 8. September hatten vor allem das Feedback der weltweiten Angular-Community im Fokus. So wurde unter dem Schlagwort „Operation Byelog“ intensiv an den auf GitHub gemeldeten Issues gearbeitet, um diese zu kategorisieren und gezielt angehen zu können. Dieses Ziel wurde erreicht. Natürlich ist die Abarbeitung der Issues noch nicht abgeschlossen – ein Zeichen eines aktiven Open-Source-Projekts ist es ja gerade, dass die Community sich in Form von Issues einbringt. In Zukunft soll die initiale Bearbeitung neuer Pull Requests und Issues innerhalb eines Zeitfensters von maximal zwei Wochen erfolgen. Allein seit Mitte Oktober wurden bis zum Release von Angular 11 über 340 Issues als erledigt markiert (Abb. 1).

sitterberg_angular11_1.tif_fmt1.jpgAbb. 1: Erledigte Issues

Auch das Thema Transparenz, ein häufig geäußerter Kritikpunkt, wird aktiv angegangen: So ist nun unter [1] die Roadmap des Angular-Projekts zu finden. Sie spiegelt die aktuelle Einschätzung und Planung zu den wichtigsten Themen aus Sicht der Angular-Core-Entwickler wider. Angular ist dank des reichhaltigen Ökosystems inzwischen mehr als nur das Framework im Zentrum. Umso wichtiger, dass auch externe Entwickler und Contributors die Möglichkeit bekommen, ihre Planung entsprechend auszurichten.

Das Major-Release Angular 11 bringt natürlich auch technische Neuerungen rund um die Plattform, das Angular CLI, Material Components und TypeScript mit. Alle Bereiche werden wir uns im Folgenden im Detail ansehen.

TypeScript

TypeScript entwickelt sich kontinuierlich weiter und Angular hält Schritt: Mit Angular 11 wird der Support für TypeScript 3.9 eingestellt, TypeScript 4.0 ist nun nötig. Das Update ist vor allem auch deshalb wichtig, da mit TypeScript 4.1 bald eine Optimierung ausgerollt werden soll, die den Angular-Compiler ngcc bis zu viermal schneller machen soll.

Darüber hinaus bietet TypeScript 4.0 einige weitere interessante Neuerungen. So wurde die Typinferenz bei TypeScript-Klassen verbessert: Auch wenn der Typ der Properties area und sideLength nicht explizit angegeben ist, kann TypeScript diese anhand der Wertzuweisungen im Konstruktor erkennen. So bekommt die Property sideLength den Typ number (Listing 1). Falls nicht alle Codepfade innerhalb des Konstruktors sicher zu einer Wertzuweisung führen, wird die Property als potenziell undefined markiert. Daher hat die Property area im Beispiel den Typ number | undefined.

Listing 1

class Square {  // Bisher waren beide Properties vom // Typ 'any' sideLength; // Typ 'number' area; // Typ 'number | undefined' constructor(sideLength: number) { this.sideLength = sideLength; if (Math.random()) { this.area = sideLength**2; } } }

Mit TypeScript 4.0 wurden auch neue (Zuweisungs-)Operatoren hinzugefügt. Wie aus vielen anderen Sprachen bekannt, gab es auch in TypeScript bisher schon Zuweisungsoperatoren wie a+=b; (entspricht a=a+b;) oder a-=b; (entspricht a=a-b;). Nun werden solche Operatoren entsprechend des ECMAScript-Standards auch für die Verknüpfungen &&, || und ?? hinzugefügt. Es gibt nun also die folgenden Zuweisungsoperatoren:

  • a &&= b (entspricht a && a = b),

  • a ||= b (entspricht a || a = b, kann auch geschrieben werden als if(!a){ a = b; }) und

  • a ??= b (entspricht a ?? a = b).

Wichtig ist bei allen diesen Operatoren, dass die Zuweisung nur geschieht, wenn sie notwendig ist. Bei a||=b etwa geschieht die Zuweisung nur dann, wenn der Wert von a falsy (also etwa 0, null oder undefined) ist.

Eine kleine Verbesserung wurde für den catch(error)-Block in try-catch-Statements eingeführt: Bisher war eine Typdeklaration des übergebenen error-Parameters nicht möglich, da er immer den Typen any hatte. Somit hatte TypeScript keine Möglichkeit, Checks auf Zugriffe durchzuführen. Nun ist es auch möglich, unknown als Typ anzugeben. Das ist zwar kein definitiver Typ, allerdings erlaubt TypeScript Zugriffe auf unkown-Variablen nur dann, wenn sie durch einen Type Guard abgesichert werden. So kann an dieser Stelle Typsicherheit dazugewonnen werden, wie in Listing 2 zu sehen ist. In zukünftigen TypeScript-Versionen soll eventuell eine Compileroption hinzugefügt werden, mit der der unknow-Typ an dieser Stelle dann erzwungen würde.

Listing 2

try { // ... } catch (e: unknown) { console.log(e.toUpperCase()); // Error: Object is of type 'unknown'. if (typeof e === "string") {  // Type-Narrowing: 'e' ist vom Typ 'string'. console.log(e.toUpperCase()); } }

Zudem wurde mit der neuen Type-Script-Version die Build-Geschwindigkeit und die Editorunterstützung durch den Language Service verbessert.

Mit der neuen Major-Version gab es auch einige Breaking Changes. So wurde document.origin entfernt, da dies ohnehin nur in alten IE und Safari-Versionen funktionierte. Stattdessen sollte self.origin verwendet werden. Zudem wird nun ein Fehler geworfen, wenn versucht wird, eine Objekt-Property mit einem set- bzw. get-Accessor zur überschreiben. Das gilt auch im umgekehrten Fall (Überschreiben eines Setters/Getters mit einer reinen Property).

Der delete-Operator konnte bisher auf alle Properties angewendet werden. In Zukunft kann delete nur noch angewendet werden, wenn die zu entfernende Property als optional gekennzeichnet ist.

Update auf Angular 11

Wer das offizielle Angular CLI verwendet, ist beim Thema Update fein raus: Selbst wenn man nicht kontinuierlich auf die aktuelle Version migriert hat, wird man durch das Werkzeug bei Updates gut unterstützt. Bei einem kleinen Projekt ist das Update innerhalb weniger Minuten erledigt. Bei komplexen Projekten, die umfangreichen Gebrauch von den Angular APIs machen, ist typischerweise ein Aufwand von einer bis wenigen Stunden realistisch. Das Vorgehen ist gewohnt komfortabel und einfach. Das Angular CLI wird mit der update-Task aufgerufen:

ng update @angular/core @angular/cli

Danach sollten alle Tests ausgeführt werden, um potenzielle Regressionen aufzuzeigen. Ich empfehle, dass wirklich jeder in eine sinnvolle Testabdeckung investiert.

Wer sich über die Details eines Updates informieren möchte, findet dazu eine interaktive Anwendung unter [2]. Anhand der Ausgabe kann auch eine manuelle Migration auf Angular 11 unterstützt werden.

CLI

Nach dem Update auf Angular CLI 11 ist die erste und offensichtlichste Neuerung die aktualisierte Logausgabe der Befehle ng serve und ng build. Damit soll eine bessere Übersicht über die erzeugten Bundles und deren Größe geschaffen werden. Dabei werden die Grund-Bundles der Anwendung separat von den Lazy-Loading Bundles aufgeführt. Letztere sind nun nach Größe sortiert. In Abbildung 2 und 3 sind die alte und die neue Ausgabe von ng serve --prod beispielhaft gegenübergestellt.

sitterberg_angular11_2.tif_fmt1.jpgAbb. 2: Alte Ausgabe von ng serve --prod
sitterberg_angular11_3.tif_fmt1.jpgAbb. 3: Neue, geordnete und übersichtliche Ausgabe von ng serve –prod

Werden innerhalb des Projekts Google-Fonts eingebunden, so werden diese nun als Teil des CLI Prod Builds als separater Link in die index.html eingebettet, wenn die Property "optimization": true in der angular.json gesetzt ist. Diese Optimierung erlaubt die Fonts parallel zum Anwendungsstart zu laden, und nicht erst als Teil der Anwendungs-Bundles. Damit reduziert sich praktischerweise auch der Umfang des Anwendungs-Bundles.

Wird eine Anwendung entwickelt, kann es vorkommen, dass das Set-up der Anwendung zur Entwicklungszeit ein anderes ist als das der Anwendung zur Produktionslaufzeit. Etwa wenn Backend und/oder Frontend zur Produktionslaufzeit in einer Umgebung laufen, die spezielle Sicherheitsfeatures erfordert zum Beispiel eine CSP oder die Types moderner Browser. Beide Features werden vom Browser aber nur aktiviert, wenn der Server spezielle Header mitschickt. Da im Angular CLI Dev Server aber keine Custom Header gesetzt werden konnten, konnten diese Features bisher nicht leicht zur Entwicklungszeit simuliert werden. Mit Angular CLI 11 gibt es nun die Möglichkeit, Custom Header in der angular.json als headers-Property innerhalb der architect.build.options zu hinterlegen. Die headers-Property ist dabei eine Key-Value-Map, in der Key der Name des Headers ist und Value der entsprechende Wert. So lässt sich beispielsweise ein CSP-Header auf folgende Weise spezifizieren:

"headers": { "Content-Security-Policy": "default-src 'self'" }

Die Möglichkeit, solche Header zu setzen, wurde v. a. in Hinblick auf die sogenannten Trusted Types eingebaut. Diese sind ein neues Sicherheitsfeature in Browsern und sollen Cross-Site-Scripting-Attacken noch effektiver verhindern. Auch Angular 11 nutzt sie, wenn möglich.

Ein Feature, das speziell Library-Autoren die Arbeit erleichtern soll, sind die sogenannten Declaration-Maps. Diese sollen es Editoren und IDEs ermöglichen, bei Nutzung von „Go to Definition“ direkt in den (lokalen) Library-Quellcode zu springen und nicht in die gebauten Library-Dateien innerhalb des /dist-Ordners.

Falls mit der neuen Angular-CLI-Version zwei Angular-Anwendungen parallel gestartet werden, beschwert sich Angular nun nicht mehr wie früher über einen bereits belegten Port. Stattdessen wird der Entwickler nun direkt gefragt, ob die Anwendung auf einem anderen freien Port gestartet werden soll. Der freie Port wird dabei zufällig aus der Menge der freien Ports gewählt.

Wird mit dem Angular CLI ein neues Projekt angelegt, so wurde vom CLI schon bisher immer abgefragt, ob z. B. ein Style Preprocessor wie SCSS verwendet und Angular-Routing vorkonfiguriert werden soll. Mit Version 11 kommt nun ei neuer sogenannter Prompt hinzu, der fragt, ob die App im strikten Modus angelegt werden soll. Dadurch werden zum einen die strikten Type Checks von TypeScript ("strict":true in der tsconfig) aktiviert, etwa die Strict-Null-Checks oder die Strict Property Initialization. Zum anderen führt der Angular-Compiler diese ...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang