Angular Buch Team
 

Angular 13 ist da!

03.11.2021

Noch vor dem Jahresende erschien Anfang November 2021 die neue Major-Version 13 von Angular. Auch diese Version bringt keine großen Änderungen an der Oberfläche des Frameworks mit, sondern verbessert vor allem Details im Hintergrund. Es gibt ein paar wenige Breaking Changes, die aber für die meisten Entwicklerinnen und Entwickler nicht interessant sein dürften.

Wir stellen in diesem Blogpost wie immer die wichtigsten Neuigkeiten vor. Den Code des Beispielprojekts BookMonkey aus dem Angular-Buch halten wir stets auf GitHub aktuell.

Die offizielle Mitteilung zum neuen Release finden Sie im englischsprachigen Angular-Blog. Im Changelog von Angular und der Angular CLI finden Sie außerdem alle Details zum neuen Release.

Die Update-Infos für neuere Versionen von Angular finden Sie in separaten Blogartikeln. Wenn Sie das Update durchführen möchten, lesen Sie bitte alle Artikel in der gegebenen Reihenfolge.

Projekt updaten

Wenn Sie Ihr bestehendes Projekt aktualisieren möchten, folgen Sie bitte den Instruktionen im Angular Update Guide. Mithilfe des Befehls ng update erhalten Sie außerdem Infos zu möglichen Updates direkt im Projekt.

# Projekt auf Angular 13 aktualisieren
npx @angular/cli@13 update @angular/core@13 @angular/cli@13

Bitte beachten Sie, dass es noch einige Zeit dauern kann, bis Community-Projekte wie NgRx oder Nrwl Nx ebenso mit Angular 13 kompatibel sind.

Neue Versionen: Node.js, TypeScript und RxJS

Angular 13 benötigt die folgenden Versionen von Node.js, TypeScript und RxJS:

  • Node.js: mindestens Version 12.20.0. Außerdem wird jetzt auch Node 16 unterstützt.
  • TypeScript: mindestens Version 4.4.2. Ältere Versionen werden nicht mehr unterstützt.
  • RxJS: Bei neu angelegten Angular-Projekten wird jetzt die Bibliothek RxJS in der aktuellen Version 7 genutzt. RxJS 6 wird weiterhin unterstützt. Bei bestehenden Projekten wird die Versionsnummer nicht automatisch erhöht.

Test Module Teardown

Schon mit Angular 12.1 wurde das sogenannte Test Module Teardown eingeführt. Mit Angular 13 ist das Teardown nun automatisch aktiv, siehe Commit. Diese Option, die bisher freiwillig aktiviert werden konnte, sorgt dafür, dass beim Unit-Testing mit dem TestBed das erzeugte Modul nach dem Test wieder zerstört wird. Dabei wird z. B. das DOM-Element der erzeugten Komponente wieder entfernt. Die Option destroyAfterEach kann für jeden Test separat aktiviert werden:

TestBed.configureTestingModule({
  teardown: { destroyAfterEach: true },
  // ...
});

Alternativ ist auch eine globale Einstellung in der Datei test.ts möglich. Für neue Projekte mit Angular 13 ist das Test Module Teardown per default eingeschaltet. Für existierende Apps wird das Teardown zunächst explizit deaktiviert, sodass keine Anpassungen im Code notwendig sind.

Für weitere Informationen empfehlen wir den Blogpost von Lars Gyrup Brink Nielsen.

Vereinfachte Schnittstelle für Dynamic Components

Mit der Schnittstelle der Klasse ViewContainerRef können Komponenteninstanzen dynamisch zur Laufzeit der Anwendung erzeugt werden. Dafür war es bisher notwendig, den ComponentFactoryResolver zu verwenden, um zunächst eine Factory für die jeweilige Komponente zu erstellen. Das war aufwendig und erzeugte viel Code.

Die Schnittstelle für die Methode createComponent() wurde mit Angular 13 vereinfacht, siehe Commit. Jetzt ist es möglich, direkt eine Komponentenklasse zu übergeben, die dann in einem ViewContainer gerendert wird. Das folgende Beispiel zeigt (stark vereinfacht!), wie eine Komponente dynamisch im ViewContainer einer Direktive erstellt werden kann:

import { ViewContainerRef } from '@angular/core';
import { MyComponent } from './my.component';

@Directive({ /* ... */ })
export class MyDirective {
  constructor(private vcr: ViewContainerRef) {
    this.vcr.createComponent(MyComponent);
  }
}

Zusammen mit Dynamic Imports kann die betreffende Komponente sogar "lazy" geladen werden. Sie wird in ein eigenes Bundle verpackt und erst beim Aufruf von import() tatsächlich heruntergeladen. Es ist damit nun noch einfacher, einzelne Komponenten auszulagern separat bereitzustellen.

import('./my.component').then(m => {
  this.vcr.createComponent(m.MyComponent);
});

Persistent Cache

In Projekten mit Angular 13 ist der neue Persistent Disk Cache automatisch aktiv. Dabei werden Teile der gebauten Anwendung zwischengespeichert, um zukünftige Builds zu beschleunigen. Der Cache kann über die angular.json konfiguriert werden:

{
  // ...
  "cli": {
    "cache": {
      "enabled": true
    }
  }
}

Informationen zur Konfiguration des Build Cache finden Sie in der Angular-Dokumentation.

Support für IE11 eingestellt

Die Unterstützung für den Internet Explorer 11 wurde entfernt. Nachdem in der letzen Version der Support bereits "deprecated" wurde, ist Angular jetzt offiziell nicht mehr im Internet Explorer lauffähig.

Bei der Migration zu Angular 13 werden deshalb einige Einträge aus der polyfills.ts entfernt. Außerdem ist Differential Loading, das mit Angular 8 eingeführt wurde, nicht mehr notwendig. Dabei wurden für ältere Browser separate Bundles in ES5 gebaut. Da alle aktuellen Browser auch modernere Varianten von JavaScript unterstützen, wird Differential Loading nicht mehr genutzt.

Bibliotheken mit Ivy-Compilation

Nachdem der neue Renderer Ivy eingeführt wurde, musste die Kompatibilität mit Anwendungen gewährt werden, die noch auf die veraltete View Engine setzten. Dafür wurde der Angular Compatibility Compiler (ngcc) entwickelt: Alle Bibliotheken, die auf NPM veröffentlicht werden, mussten zunächst weiterhin mit der View Engine kompiliert werden. Beim Build einer Ivy-Anwendung wurde automatisch der ngcc aktiv, um die Anweisungen in Ivy-Instruktionen zu übersetzen.

Dieser Prozess braucht Zeit. Möglicherweise haben Sie diese Ausgabe beim ng serve schon einmal gesehen – sie stammt vom ngcc:

Compiling @angular/core : es2015 as esm2015
Compiling @angular/common : es2015 as esm2015
Compiling @angular/platform-browser : es2015 as esm2015
Compiling @angular/common/http : es2015 as esm2015

Seit Angular 13 können Bibliotheken direkt in Ivy-Instruktionen kompiliert und veröffentlicht werden. Der Code ist dann nicht mehr mit der View Engine kompatibel. Der ngcc wird damit weiter an Bedeutung verlieren und künftig entfernt werden können. Die View Engine wird seit Angular 13 nicht mehr unterstützt.

Mehr Infos zum Veröffentlichen von Bibliotheken mit Ivy finden Sie in der Angular-Dokumentation.

Neue Methoden für Reactive Forms

Für die Formularverarbeitung mit Reactive Forms wurden neue Methoden hinzugefügt, siehe Commit:

  • hasValidator, hasAsyncValidator
  • addValidators, addAsyncValidators
  • removeValidators, removeAsyncValidators

Damit ist es möglich, programmatisch zu prüfen, ob ein bestimmter Validator auf einem Control vorhanden ist, um z. B. Required-Felder optisch zu markieren. Außerdem können einzelne Validatoren dynamisch hinzugefügt oder entfernt werden. Das kann z. B. in Abhängigkeit von anderen Formularwerten implementiert werden. Bisher war es nur möglich, alle Validatoren eines Controls zu setzen oder zu entfernen.

// prüfen, ob required-Validator auf dem Control vorhanden ist
isRequired(controlName: string) {
  const control = this.form.get(controlName);
  return !!control && control.hasValidator(Validators.required)
}

// required-Validator dynamisch hinzufügen
addRequired(controlName: string) {
  const control = this.form.get(controlName)!;

  control.addValidators(Validators.required);
  control.updateValueAndValidity();
}

Wir haben ein funktionierendes Beispiel auf GitHub bereitgestellt.

Auch die Typisierung bei den Formularen hat sich verbessert. Es wurde ein neuer Typ FormControlStatus eingeführt, welcher nun bei form.statusund form.statusChanges zum Einsatz kommt, siehe Commit:

export type FormControlStatus = 'VALID'|'INVALID'|'PENDING'|'DISABLED';

Sonstiges

  • $localize stable: Die Funktion $localize zur Übersetzung von Texten in der Anwendung gilt jetzt als stable. Siehe auch dieser Beitrag im Angular-Blog: Angular localization with Ivy.
  • deployUrl: Die Option deployUrl für ng build ist nun deprecated. Falls Sie ein ähnliches Verhalten wiederherstellen möchten, eignet sich eine Kombination aus dem Parameter baseHref und dem InjectionToken APP_BASE_HREF.
  • Event für routerLinkActive: Die Direktive routerLinkActive emittiert das Event isActiveChange, wenn sich der Aktivitätsstatus dieses Links ändert. Das kann man nutzen, um weitere Aktionen anzustoßen, wenn ein RouterLink aktiviert oder deaktiviert wird, siehe Commit.
  • Adobe Fonts Inlining: Fonts Inlining wurde bisher "out of the box" für Google Fonts unterstützt. Dabei werden beim Build die Font-Dateien heruntergeladen und zusammen mit der gebauten Anwendung abgelegt. Dieses Verfahren wird jetzt auch für Adobe Fonts unterstützt.
  • loadChildren String Syntax: Die veraltete String-Syntax für Lazy-Loading mit loadChildren wurde entfernt. Die alte Schreibweise ist seit Angular 9 deprecated und sollte ohnehin nicht mehr genutzt werden.
  • Zeitzone für DatePipe: Die DatePipe nutzt ein neues InjectionToken DATE_PIPE_DEFAULT_TIMEZONE, mit dem die Zeitzone eingestellt werden kann, siehe Commit.
  • min/max-Validatoren mit null: Bei Template-Driven Forms können die Validatoren für min und max nun auch den Eingabewert null verarbeiten. Der Validator wird dadurch deaktiviert. Ein ähnliches Verhalten wird bereits von minLength und maxLength unterstützt. Siehe Commit.
  • renderModuleFactory entfernt: Die Funktion renderModuleFactory, die im Zusammenhang mit Server-Side Rendering relevant ist, steht nicht mehr zur Verfügung. Stattdessen soll die Funktion renderModule genutzt werden.

Es hat sich also einiges getan, und es wurden viele Punkte aus der Sektion "In progress" von der Roadmap (Stand: 19.05.2021) abgearbeitet. Als einer der wichtigsten offenen Punkte sind nun noch die optionalen NgModules zu sehen, für die es jüngst eine Befragung der Community gab (siehe RFC). Die Roadmap für die zukünftige Entwicklung von Angular wird regelmäßig in der Dokumentation veröffentlicht: https://angular.io/guide/roadmap.

Wir wünschen Ihnen viel Spaß mit Angular 13! Haben Sie Fragen zur neuen Version, zum Update oder zu Angular? Schreiben Sie uns!

Viel Spaß wünschen Danny, Ferdinand und Johannes

Titelbild: Blick vom Poon Hill, Nepal, 2018. Foto von Ferdinand Malcher

Zurück
Suggestions? Feedback? Bugs? Please fork/edit this page on Github.