Neues Major Release

Angular 10 – ein runder Geburtstag
Keine Kommentare

Angular 10 ist da! Karsten Sitterberg wirft einen Blick auf die neuen Features, die das neue Major Release mit sich bringt. Neuigkeiten gibt es unter anderem bei TypeScript, Angular CLI und auf Seiten des Routers.

Nachdem das Angular 9-Release doch mit einigen Extrarunden bedacht war, kommt nun Angular 10. Aufgrund der spät erschienenen Angular 9 Version, ist auch Angular 10 nicht ganz im ursprünglich definierten Rhythmus. Und auch bei Angular Version 10 stellt sich wie immer die Frage: Lohnt das Update? In diesem Beitrag betrachten wir, was Angular 10 mit sich bringt und geben Tipps für das Update.

Im Gegensatz zu Angular 9 ist das Angular 10-Release kleiner. Aber das dürfte auch nicht überraschen, wurde in Angular 9 mit Ivy doch ein vollständig neues Renderingsystem als neuer Standard eingeführt.

Vorweg lässt sich sagen: Wie immer gibt es TypeScript Updates und Bugfixes, sodass ein Update schlichtweg anzuraten ist. Wer noch mit älteren Angular Versionen unterwegs ist (zum Beispiel Angular 4 oder Angular 6) und sich bisher dachte, dass ständiges Aktualisieren ja auch viel Arbeit ist, dem sei gesagt: Große Versionssprünge gehen mit mehr Risiko und Aufwand einher, als kontinuierlich kleinere Updates mit zu gehen. Das geht soweit, dass offiziell selbst für größere Versionssprünge empfohlen wird, inkrementell vorzugehen: Soll etwa von Version 8 auf Version 10 aktualisiert werden, so sollte zunächst von Version 8 auf Version 9 angehoben werden. Dort sollen dann alle Fehler, Tests, etc. gefixed werden, um dann das Update auf Version 10 durchzuführen. Schauen wir uns nun also an, was sich seit Angular 9.0 getan hat.

Angular 10: Neuerungen bei TypeScript

Bereits mit Angular 9.1 wurde auf TypeScript 3.8 aktualisiert. Für Angular 10 wurde die Typescript-Version wiederum angehoben, es wird nun Version 3.9 von Typescript verwendet.

Im Update auf TypeScript 3.8 ist bereits die Möglichkeit hinzugekommen, ECMAScript Private Fields in Typescript zu verwenden. ECMAScript Private Fields können – ähnlich wie herkömmliche private Variablen in Typescript – als Variablen verwendet werden, die eindeutig dem Scope einer Klasse zugeordnet sind und auch nur innerhalb dieser Klasse verwendet werden können. Die neuen Private Fields sind Teil der aktuellen ECMAScript-Spezifikation. Damit behalten sie, im Gegensatz zu normalen private Variablen, ihre Scoping-Eigenschaften, auch nach der Transpilation von TypeScript zu ECMAScript bzw. Javascript und auch im Browser.

Im folgendem Listing ist zu sehen, wie Private Fields erzeugt werden: Das Erkennungszeichen von Private Fields ist das Hash-Zeichen (#), alle Private Fields beginnen mit diesem Zeichen. Unten ist auch die Fehlermeldung gezeigt, die bei Zugriff auf ein Private Field von außen generiert wird.

class Person {
    #name: string

    constructor(name: string) {
        this.#name = name;
    }

    greet() {
        console.log(`Hello, I am ${this.#name}!`);
    }
}

let me = new Person("Karsten Sitterberg");

me.#name
//     ~~~~~
// Property '#name' is not accessible outside class 'Person' because it has a private identifier.

Variablen, die durch das # als Private Fields gekennzeichnet werden, können keine Modifier wie private oder public tragen.

Das Update auf TypeScript 3.9 enthält unter anderem ein paar Verbesserungen, um die Entwicklung mit Editoren wie Visual Studio Code oder Sublime Text 3 angenehmer zu gestalten. Dazu folgen später weitere Details.

Mit der neuen TypeScript-Version kommen allerdings auch ein paar Breaking Changes. Diese beruhen im wesentlichen auf genaueren, teils strengeren Typ-Checks. So sind zum Beispiel Typ-Checks auf Intersection-Types in Verbindung mit optionalen Feldern strikter geworden. Dazu folgendes Beispiel:

interface A {
    a: number; // Dies ist eine 'number'!
}
interface B {
    b: string;
}

interface C {
    a?: boolean; // Dies ist ein 'boolean'!
    b: string;
}

let unionAB: A & B = {a: 42, b: "foo"};
let singleC: C = {a:false, b:"bar"};

singleC = unionAB;

Obwohl der Typ A nicht zum Typ C passt, hat TypeScript bisher die Zuweisung von unionAB an singleC nicht verhindert, da C kompatibel zu B ist. In TypeScript 3.9 wird dies nun als Fehler erkannt:

Type 'A & B' is not assignable to type 'C'.
  Types of property 'a' are incompatible.
    Type 'number' is not assignable to type 'boolean | undefined'.

Auch beim Handling von generischen Typ-Parametern ist TypeScript strikter geworden. So werden Typ-Parameter, die any erweitern, zukünftig nicht mehr mit any gleichgesetzt. Während folgender Aufruf vorher problemlos möglich war, wird durch solche – meist wenig sinnvollen – Operationen in Zukunft der Fehler Property 'someDumbValue' does not exist on type 'T' geworfen.

function foo<T extends any>(arg: T) {
  arg.someDumbValue;
}

Weiterhin sind mit TypeScript 3.9 einige kompatible Änderungen hinzugekommen. Dazu gehören zum Beispiel Performance-Verbesserungen beim Compile-Vorgang. Je nach Projekt konnten durch TypeScript 3.9 bis zu 40% Compile-Zeit eingespart werden. Auch Refactorings wie beispielsweise Umbenennungen von Dateien sollen nun schneller durch IDEs umgesetzt werden können.

Bei Verwendung von Funktionen wie Promise.all() oder Promise.race() konnte es in neueren TypeScript-Versionen zu Fehlern in der Typinferenz kommen in Verbindung mit null bzw. undefined kommen, wie folgendes Beispiel zeigt:


interface Person {
    walk(): void
}

interface MichaelJackson {
    moonWalk(): void
}

async function planConcert(
      participant: Promise<Person | undefined>, 
      mj: Promise<MichaelJackson>) {
  let [person, michael] = await Promise.all([participant, mj]);
  michael.moonWalk(); // Object is possibly 'undefined'.
}

In diesem Fall konnte es passieren, dass Promises, die null oder undefined als Wert enthalten, diese Eigenschaft auf andere Promises übertragen. Im Beispiel oben ist zu sehen, dass das Promise participant den Wert undefined enthalten kann. Die Verwendung von Promise.all sorgte nun dafür, dass die Variable michael (fälschlicherweise) den Typen undefined enthielt. Dies ist mit TypeScript 3.9 nun behoben

Werden mit Angular-CLI 10 neue Projekte aufsetzt, wird eine Änderung direkt auffallen: Mit TypeScript 3.9 und Angular-CLI 10 werden “Solution Style”-tsconfig.json-Dateien unterstützt. Diese erleichtern es Editoren zu entscheiden, zu welchem Projekt eine Datei gehört. Das folgende Listing zeigt, wie das in der Praxis aussehen kann:

{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.spec.json"
    },
    {
      "path": "./e2e/tsconfig.json"
    },
    {
      "path": "./projects/my-lib/tsconfig.lib.json"
    },
    {
      "path": "./projects/my-lib/tsconfig.spec.json"
    }
  ]
}

Solution Style-tsconfig.json-Dateien sind aber nicht dazu gedacht, einen tatsächlichen Kompilationsprozess zu starten, sondern dienen lediglich als Unterstützung für Editoren, die den Language-Server von Typescript unterstützten.

Angular CLI

In Angular 10 ist neben dem oben bereits erwähnten Update auf TypeScript 3.9 und den Solution Style tsconfig’s auch die Version des Testrunners Karma auf die Version 5.0.0 angehoben worden. Außerdem wurde die --strict-Konfigurations-Option, die mit Version 9 hinzugekommen ist, in Angular CLI 10 erweitert. Wird ein Projekt im strikten Modus erzeugt, werden neben strikteren Typ-Checks und Linting-Regeln auch Coding-Regeln eingeführt, die Optimierungen verbessern sollen. Letzteres macht sich vor allem in einer zusätzlichen package.json im /src/app-Verzeichnis von Anwendungen bemerkbar, die im wesentlichen einen Eintrag sideEffects enthält.

Wenn sideEffects auf false steht, ist dies ein Hinweis an Bundling-Tools (Webpack), dass aller Code inner- und unterhalb dieses Verzeichnisses keine “nicht-lokalen Seiteneffekte” enthält. Nicht-lokale Seiteneffekte treten dann auf, wenn ein TypeScript- oder auch JavaScript-Modul Code nicht (nur) per export zur Verfügung stellt, sondern (auch) Änderungen am globalen Scope vornimmt. Polyfills enthalten z.B. nicht-lokale Seiteneffekte. Code, der solche Seiteneffekte enthält, hat negative Auswirkungen auf Tree-Shaking. Mit dem oben beschriebenen Flag wird nun gekennzeichnet, dass der Code keine Seiteneffekte hat, dadurch wird er also besser optimierbar.

Angular Camp 2020

Als Online- oder Präsenztraining!

Das 360°-Intensivtraining mit Angular-Koryphäe Manfred Steyer
Präsentiert von Entwickler Akademie


Aus einem ähnlichen Grund wurde auch eine neue Warnung eingeführt, die erzeugt wird, wenn ein CommonJS-Paket eingebunden wird. Diese Warnung wurde eingeführt, da CommonJS-Pakete häufig dazu führen, dass Anwendungen im Build nicht so gut optimiert werden können. Um diese Warnung für bestimmte Pakete zu deaktivieren, kann die Builder-Option allowedCommonJsDepedencies verwendet werden, siehe auch folgenden Code-Ausschnitt.

"build": {
  "builder": "@angular-devkit/build-angular:browser",
  "options": {
    ...
    "allowedCommonJsDepedencies": ["bootstrap"]
  },
}

In der neuen Angular-CLI-Version werden außerdem die Maximalwerte für die Bundle-Budgets strenger. Mit Budgets kann kontrolliert werden, wie groß die im Build erzeugten Bundles werden dürfen. Die dadurch erzeugte Aufmerksamkeit für von Bundlegrößen dürfte sicher dazu beitragen, dass Entwickler sich mehr mit den Möglichkeiten zur Optimierung von Angular Anwendungen beschäftigen und damit für Nutzer optimierte Ladezeiten erzielen. (Mögliche Lösungen können der Einsatz von Lazy-Loading und besserer Strukturierung der Angular Anwendung sein. Für spezifische Fragen zu dem Thema und Trainingswünsche rund um Angular freut sich der Autor über Anfragen auf sitterberg.com)

Breaking Changes

In Angular 10 wurden vor allem CLI- und Build-Optionen entfernt, die bisher bereits deprecated waren. Dazu gehören etwa ng set und ng get, die durch ng config ersetzt wurden. Um ein Profiling des CLI-Build-Prozesses zu erstellen, konnte bisher die --profile Build-Option verwendet werden. Diese wurde nun durch die Environment-Variable NG_BUILD_PROFILING ersetzt.

Sollen Source-Maps für die Vendor-Scripte erstellt werden, so ist nun nicht länger die Builder-Option vendorSourceMap zu nutzen, sondern das vendor-Flag im sourceMap-Objekt auf true zu setzen. Die Builder-Option es5BrowserSupport wiederum wurde entfernt, da die Konfiguration des Browser-Supports über die Datei .browserslistrc gesteuert wird.

Angular Material

Auch bei Angular Material gab es einige Neuerungen. Die Komponentenbibliothek, die das Google Material Design für Angular implementiert, wird gerne zur Umsetzung von typischen (Formular-)Anwendungen mit Angular eingesetzt und erfreut sich wachsender Beliebtheit. Neben einem grundlegenden Anwendungsgerüst und Komponenten, die typischerweise in Webanwendungen häufig benötigt werden, sind natürlich auch Komponenten zur Einbindung von Google Diensten wie YouTube und Google Maps vorhanden.
Google stellt dazu ein eigenes Team, dass Angular Material kontinuierlich gepflegt und weiterentwickelt. So ist es kein Wunder, dass auch zum Angular 10 Release bei Angular Material einige Neuerungen bereit stehen. Die neue 10er-Version von Material heißt übrigens – passend zum Sommer – ice-dice.

Einige Breaking-Changes finden sich auch bei Angular Material: Dabei handelt es sich in Summe um kleinere Änderungen bei Parametern von Komponenten, die auch in der Vergangenheit bereits als “deprecated” markiert waren oder, dass Parameter nunmehr erforderlich sind.
Das betrifft zum Beispiel die YouTubePlayer-Komponente, bei der der Parameter platformId im Konstruktor nun erforderlich ist. Dies hat aber keine weitergehenden Auswirkungen auf die Entwicklung mit dem YouTube-Player, da die Plattform-ID von Angular automatisch per Dependency-injection zur Verfügung gestellt wird (Injecton-Token PLATFORM_ID)
Die Anpassungen sind mit geringem Aufwand umzusetzen, sodass einem Update an dieser Stelle nichts im Wege steht.

Mit Angular Material Version 10 ist auch eine ganz neue Komponente dazu gekommen: Der viel angefragte Date-Range-Picker, mit dem sich nicht nur ein Datum, sondern ein Zeitraum auswählen lässt.
Eine Abbildung des Date-Range Pickers ist in folgender Grafik dargestellt.

date-range picker angular 10

Angular

Bereits mit Angular 9.1 wurde der Angular Compiler ngcc bezüglich seiner Geschwindigkeit deutlich optimiert. Dazu wurde die parallele Verarbeitung von Paketen durch ngcc verbessert, sodass nun der bis dahin speziell für schnellere CI-Builds empfohlene npm postinstall-Schritt zur parallelen Ivy-Kompilierung der Dependencies nun nicht mehr benötigt wird.
Ein neues Compiler-Feature erweitert die erzeugten Metadaten um Informationen über Abhängigkeiten und <ng-content>-Selektoren. Dadurch werden die Hilfen, die der Language-Server, und damit alle darauf aufsetzenden Werkzeuge dem Entwickler bieten können, speziell für den neuen Ivy-Compiler verbessert. Mit Angular 10 gibt es weitere Bug-Fixes und Verbesserungen am ngcc, etwa eine verbesserte Robustheit im Umgang mit dem ngcc-Lockfile.

Der Angular-Router wurde so erweitert, dass ein CanLoad-Guard von nun an auch einen UrlTree zurückgeben kann. Dieses Feature gibt es bisher schon beim CanActivate-Guard und kann vor allem dafür eingesetzt werden, um einen bestehenden Routing-Vorgang abzubrechen und stattdessen auf eine andere Route umzuleiten.

Mit Angular 10 kommen auch einige Breaking Changes, die im folgenden Abschnitt näher betrachtet werden.

Breaking Changes

Mit Angular 10 wird, wie weiter oben beschrieben, die aktuellste Version von TypeScript eingeführt. Damit endet gleichzeitig die Unterstützung für TypeScript 3.8 und geringer.

Das Angular immer moderner wird, macht sich auch an den per NPM verteilten Angular-Paketen bemerkbar. Diese halten sich an das sogenannte Angular Package Format (APF). Mit Angular 10 kommt nun auch das APF v10 raus. In dieser neuen Version sind die sogenannten “esm5” und “fesm5”-Dateien nicht mehr enthalten. “esm” steht dabei für ECMAScript-Module, die 5 bezieht sich auf die ECMAScript-Version, die von diesen Modulen verwendet wird. “esm5” steht somit für ECMAScript-Module in ECMAScript-Version 5.

Für “fesm5”-Module gilt im Prinzip das gleiche. Der einzige Unterschied ist, dass bei Bibliotheken, die im “fesm”-Format publiziert werden, alle einzelnen JavaScript-Dateien zu einer einzigen zusammengefügt werden. Die unterschiedlichen eingesetzten Publikationsformate erklären sich dadurch, dass je nach verwendetem (Build-)Tool ein anderes Publikationsformat zu optimalen Resultaten führt (Angular-CLI nutzt z.B. “fesm2015”). Weitere Modul-Varianten, die Angular innerhalb seiner NPM-Pakete publiziert, sind die “esm2015”-, die “fesm2015”- und “umd”-Module. Projekte, die nicht Angular-CLI und auf die “esm5/fesm5”-Module angewiesen sind, müssen diese aus den anderen Modulen durch Downleveling im Rahmen des Builds erzeugen.

Router

Breaking Changes in Bezug auf den Router betreffen dort vor allem den UrlMatcher und die Resolver. Im Typen des Matcher spiegelt sich nun die Tatsache wieder, dass der Matcher auch null zurückgeben kann. Dies muss vor allem dann berücksichtigt werden, wenn eigene Implementierungen des UrlMatcher verwendet werden.

Angular-Route-Resolver wurden so angepasst, dass sie den aktuellen Navigationsvorgang abbrechen, wenn sie ein dem EMPTY-Observable gleichwertiges Observable zurückgeben. Das bedeutet, dass ein Observable, welches zwar ein completed-Event, aber keinen eigentlichen next-Wert zurückgibt, löst ein NavigationCancel-Event des Routers aus. Ein solcher Resolver ist im folgenden Listing gezeigt:

@Injectable({providedIn: 'root'})
export class DemoGuard implements Resolve<unknown> {
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
        : Observable<unknown> | Promise<unknown> | unknown {
    return EMPTY; // Fuehrt zu 'NavigationCancel'-Event
  }
}

Soll ab Angular 10 der Navigationsvorgang zu Ende gebracht werden, so muss nun auf alle Fälle ein Observable zurückgegeben werden, das einen Wert liefert (z.B defaultIfEmpty(…), of(…), …). Dabei ist unerheblich, was für ein Wert emittiert wird (also auch ein “leeres” next-Event oder eines, das undefined enthält führen zu einer erfolgreichen Navigation). Siehe dazu folgendes Listing:

@Injectable({providedIn: 'root'})
export class DemoGuard implements Resolve<unknown> {
 
  constructor(private myService: MyService){}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
        : Observable<unknown> | Promise<unknown> | unknown {
    return this.myService.getData()
      .pipe(
        // Wurden keine Daten emittiert, nutze 'undefined' als Default
        defaultIfEmpty(undefined)
  	);
  }
}

Angular Core

Während der generische Typparameter bei ModuleWithProviders in Ivy schon seit Einführung notwendig war, war er in der ViewEngine noch immer optional. Dies wird mit Angular 10 geändert, der Parameter ist nicht länger optional. Allerdings wird es eine Angular-Migration geben, die diesen Parameter automatisch an den meisten Stellen automatisch hinzufügt. Falls mit dem alten Renderer ViewEngine eine Library eingebunden werden soll, bei der der Parameter fehlt, wird dies nun zu Fehlern führen, bis die Library aktualisiert wurde. Ein Workaround hierfür ist, entweder den Parameter skipLibChecks in der tsconfig auf false zu setzen, oder die eigene App auf Ivy umzustellen, da Ivy die von ngcc generierten Metadaten nutzen kann.

Stößt Angular auf ein unbekanntes Element, wird nun statt einer Warnung ein Fehler per console.error ausgegeben. Dieses Verhalten stört zwar die App nicht, könnte aber zu Problemen mit Bibliotheken führen, die auf Logging auf console.error reagieren.

Bisher enthielten Angular-Pakete spezielle, zur Optimierung mit dem Google Closure JavaScript Compiler genutzte jsdoc-Kommentare. Allerdings sind die mit TypeScript 3.9 erhaltenen Build-Resultate inkompatibel zu der momentanen Closure-Compiler Version. Da der Angular Support für den Closure Compiler bisher ohnehin experimentell war, wurde er nun vorübergehend herausgenommen. Nähere Informationen zum Stand von TypeScript in Verbindung mit dem Closure Compiler sind unter https://github.com/microsoft/TypeScript/issues/38374 zu finden.

Falls in einem Projekt bisher der Closure-Compiler verwendet wurde, sollte in diesen Anwendungsfällen nun der Angular-Quellcode mitgebaut werden. Die per NPM bereitgestellten Versionen von Angular sind auf Webpack/Rollup und Terser-Builds optimiert. Eine Alternative ist auch die Verwendung des Closure-Flag --compilation_level=SIMPLE. Dieses Flag erlaubt es, eine lauffähige Anwendung bauen zu können, die dann allerdings nicht die erweiterten Optimierungen des Closure Compiler enthält und somit deutlich größer wird.

Es wurden Verbesserungen am Code der Async-Pipe vorgenommen, die dazu führen können, dass ExpressionChangedAfterItHasBeenChecked-Fehler auftreten, die bisher “verschleiert” worden waren. Diese Verbesserungen bewirken auch, dass Bindings wie das folgende nur noch dann Change-Detection triggern, wenn sich der Wert von someProperty auch tatsächlich geändert hat.

[val]="(observable | async)?.someProperty"

Bisher war es so, dass auch dann Change-Detection getriggert wurde, wenn zwar das Observable einen neuen Wert emittiert hat, der Wert von someProperty sich aber nicht geändert hat. Falls der so gesparte Change-Detection-Lauf weiterhin benötigt wird, so sollte man sich direkt auf das Observable subscriben und changeDetectorRef.markForCheck() aufrufen.

Common

In der Angular-Date-Pipe oder der formatDate()-Methode können die Parameter b oder auch B als Formatierungs-Option verwendet werden. Diese können zum Ausgeben von Tageszeiten wie “mittags” oder “morgens” verwendet werden. Hier gab es Fehler bei der Darstellung von Zeiten, die um Mitternacht lagen. Dieses Verhalten wurde nun geändert, sodass die korrekte Tageszeit ausgegeben wird.

Forms

Formulare gehören zu jeder Geschäftsanwendung dazu. Angular bietet mit den Template-Driven- und den Reactive-Forms gleich zwei Varianten für die Umsetzung von Formulare an.

Eine spezielle Variante von Forms sind die Number-Type Inputs. Aus Kompatibilitätsgründen zu IE9 wurde bei diesen Number-Inputs jedesmal ein Angular-Form-Change getriggert, wenn entweder ein OnChanges- oder ein OnInput-Events getriggert. Dies führte in modernen Browsern zu doppelten valueChanges-Events. Mit Angular 10 werden Value-Changes nun nur noch onInput getriggert. Soll eine Anwendung weiterhin IE9 unterstützen, muss in diesem Fall nun ein direkter Listener auf das OnChange-Event registriert werden und damit die onChange()-Methode des NumberValueAccessor manuell aufgerufen werden. Dies muss auch beachtet werden, wenn mit alten Versionen von Webdriver gearbeitet wird.

Auch Validatoren gehören zum essentiellen Repertoire von Formularen. Mit den minLength– und maxLength-Validatoren konnte es bisher zu unerwünschten Validationsfehlern kommen. Wenn die FormControl etwa Werte ohne numerische length-Eigenschaft hatte, zum Beispiel 0 oder auch false, wurde ein Validationsfehler ausgegeben. Dieses Verhalten wurde nun geändert, die Validatoren werden nur noch Werte validieren, die auch ein length-Property besitzen. Um Code anzupassen, der auf dem alten Verhalten beruhte, sollten nun zusätzliche Validatoren wie in oder requiredTrue hinzugefügt werden.

Service Worker

Um progressive Web App (PWA) zu bauen, sind Service-Worker unerlässlich. (Wer mehr über PWAs erfahren möchte, sei auch auf mein Video-Tutorial zu dem Thema verwiesen: https://tutorials.entwickler.de/tutorials/progressive-web-applications)

Service Worker ermöglichen es, viele für moderne Apps wichtige Eigenschaften umzusetzen. Dazu gehört in erster Linie Offline-Fähigkeit. Bisher hat der Angular- Service Worker zwecks Caching auch den Vary-Header von HTTP-Antworten ausgewertet. Dies konnte das Abrufen von gecachten Assets verhindern und hat zum Teil auch, je nach Browser, zu inkonsistentem Verhalten geführt. Mit Angular 10 werden Vary-Header nun ignoriert, wenn Inhalte aus dem Service-Worker Cache geholt werden. Wenn die Anwendung auf den Header reagieren können muss, so sollte der Angular-Service-Worker so konfiguriert werden, dass er die entsprechenden Ressourcen nicht cachen soll. Die nicht zu cachenden Ressourcen können in der zum Angular-Service-Worker gehörenden ngsw-config.json eingestellt werden.

Fazit

Angular 10 ist ein super Release! Man kann sich bereits den einen oder anderen Entwickler vorstellen, dem zu wenig neue Features geliefert werden, sicher. Auf der anderen Seite ist das Update auf Angular 10 von Angular 9 mit extrem wenig Aufwand zu machen und gerade in großen Enterprise-Projekten, in denen gerne mal ein Framework-Update als “Epic” statt als “Story” eingeplant wird, kann Angular 10 somit punkten.
Das Update selbst wird durch das Angular CLI unterstützt, so dass das folgende Kommando in den meisten Projekten ausreichend sein sollte:

ng update @angular/cli @angular/core

Anschließend ist es natürlich sehr empfehlenswert, die Unit- und Integrationstests laufen zu lassen. Und die dürfen genauso in keinem Projekt fehlen, wie der Wille auf die jeweils aktuellste Angular Version upzudaten!

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -