Erste Vorkehrungen für Angular 2

Post von Patrick Roos auf Medium.com

Qualitätsziele von Angular 2

In unserer Plattform adhook.io haben wir in Zukunft die gleiche Herausforderung wie viele andere Web-Plattformen: Die Migration nach Angular 2. Dieser Blog-Post beschreibt die ersten Vorkehrungen, die eine Migration nach Angular 2 unterstützen.

Technische Schulden

Man kann den Einsatz von AngularJS (1.x) als technische Schuld führen. Im iSAQB Advanced Modul ‘AGILA’ mit Stefan Toth lernt man folgendes im Umgang mit technischen Schulden. Bei technischen Schulden hat man grundsätzlich folgende Handlungsoptionen (aus Buch ‘Vorgehensmuster für Software-Architektur’):

  • Schuldenfortzahlung: Man behandelt das Problem nicht weiter, sondern akzeptiert es.
    Angular Beispiel: Man setzt weiterhin AngularJS (1.x) ein, kann das eingegangene Risiko gut abschätzen und geht diese weiterhin ein.
  • Schuldenrückzahlung: Man beseitigt die Schuld durch Umstrukturierungen, Migration, Portierung, etc.
    Angular Beispiel: Man migriert von AngularJS (1.x) nach Angular (2.x).
  • Umschuldung: Man ersetzt die aktuelle Lösung durch eine gute, aber nicht perfekte Lösung, die eine geringere Schuldenlast verursacht.
    Angular Beispiel: Man migriert z.B. einzelne fachliche oder technische Aspekte nach Angular 2 (‘hybrid Szenario’).

Technische Schulden sind unumgänglich. Wichtig ist, dass man sie aktiv listet, diese kontinuierlich bewertet und falls notwendig, entsprechende Massnahmen trifft. Für adhook.io haben wir uns in einem ersten Schritt für die Handlungsoption Umschuldung entschieden, wie die folgenden Kapiteln zeigen.

Erste Schritte Richtung Angular (2.x)

Dieses Kapitel beschreibt die ersten Vorkehrungen sowie die Erfahrungen Richtung Angular 2 anhand eines Praxisbeispiels von adhook.io.

Vorbereitungen

angular.io setzt die folgenden Vorbereitungen für eine Migration nach Angular 2 voraus:

  1. Folge der AngularJS Style Guide von John Papa
    Naja, machen wir +/- 😉
  2. Benutze einen Module Loader wie z.B. SystemJS oder WebPack
    Kommt zum aktuellen Zeitpunkt nicht in Frage, da wir keinen unmittelbaren Mehrwert daraus erhalten.
  3. Migriere dein Projekt nach Typescript
    Ja — macht aktuell für uns Sinn! Typensicheres Javascript reduziert mögliche Fehlerquellen in unserer zukünftigen Frontend-Entwicklung.
  4. Benutze das ‘Component Directive’ Konstrukt von >= AngularJS 1.5.x
    Ja — macht aktuell für uns Sinn! Wir können so den Komponenten-Ansatz von Angular 2 besser kennen lernen und der Migrationsaufwand nach Angular 2 minimieren.

Wie aus den Kommentaren zu den einzelnen Punkten ersichtlich ist, haben wir uns aktuell für die Punkte 3 und 4 entschieden, welche wir punktuell an neuen Features umsetzen möchten. Die Umsetzung zeigen die folgenden Kapiteln.

Typescript Unterstützung

Typescript ist ein typisiertes Superset von Javascript, mit welchem man nach plain Javascript transpilieren kann. Dank diesem Superset-Ansatz lässt sich eine Javascript-Datei *.js einfach nach *.ts umbenennen — fertig.

Umgebungssetup
Damit man im eigenen AngularJS (1.x) Projekt nach Typescript transpilieren kann, muss man folgende Schritte ausführen:

  1. Installation von Typescript
    npm install -g typescript
  2. Installation des Typings Definition Loader
    npm install -g typings
  3. Benötigte Typings, wie z.B. die von AngularJS, etc. installieren
    typings install dt~jquery dt~angular dt~angular-route \
    dt~angular-resource dt~angular-mocks dt~angular-animate \
    dt~jasmine -- --save --global
  4. Hinzufügen der Typescript-Konfiguration (tsconfig.json)
    Das tsconfig.json im Projekt-Verzeichnis analog package.json ablegen.
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "suppressImplicitAnyIndexErrors": true
  },
  "exclude": [
    "node_modules"
  ]
}

5. Typescript-Watcher laufen lassen

tsc -w

Fertig, ab sofort kann im ganzen Projekt mit Typescript gearbeitet werden!

Komponentenbasiert in AngularJS 1.x

Da laufend Anpassungen an Funktionalitäten oder gar neue Features in adhook.io hinzukommen, haben wir uns entschlossen, direkt ein neues Feature mit dem neuen Komponentenansatz von Angular umzusetzen. Dank dem Komponent-Aspekt in Angular 1.5 ist dies bereits jetzt möglich, um so einen sanfteren Übergang von Angular 1.x nach Angular 2 zu erhalten. Angular 2 propagiert nicht mehr das klassische MVC-Pattern, sondern schlägt den eben diesen Komponentenansatz vor.

Komponentendefinition in Angular 2
Laut angular.io ist eine Komponente in Angular folgendes:

A component controls a patch of screen called a view
For example, the following views are controlled by components:

Das folgende Bild zeigt diesen Komponentenansatz relativ schön:

https://angular.io/docs/ts/latest/guide/architecture.html

Die Umsetzung am Praxisbeispiel
In adhook.io haben wir nun eine View erstellt, welche aus zwei Child-Views besteht. Fachlich ist es eine Ansicht, welche die Resultate aus dem A/B-Testing von digitalen Werbeanzeigen enthalten wird. Die Ansicht besteht aus zwei Teilansichten — eine Übersicht und eine Detailansicht.

Diese lassen sich nun schön mit dem Komponentenansatz umsetzen:

  • Parent-Komponente (A/B Testing View)
    abTestingComponent
  • Child-Komponente 1 (A/B Testing Übersicht)
    abTestingOverviewComponent
  • Child-Komponente 2 (A/B Testing Details)
    abTestingDetailsComponent

Eine Komponente besteht in Angular 1.x aus den folgenden Elementen:

  • Metadaten für die Registrierung einer Komponente in Angular 1.5.x:
/**
 * Created by patrick on 05.10.16.
 */
angular.module('adhook.client').component("abTestingComponent", {
  templateUrl: 'components/promotion/abTesting/abTesting.html',
  controller: AbTestingController
});
  • Controller
class AbTestingController {
  tabData:any;
  logger : angular.ILogService;

  static $inject = ['$log'];

  constructor($log: angular.ILogService) {
    $log.info('logger called.');
    //...
  }

  onClick(points, evt) {
    //..
  }

  initOverview = function() {
    //..
  }

  initAds = function() {
   //..
  };

};
  • Template (Markup)
<div>
  <div>
    <div ng-show="$ctrl.tabData.selectedTab === 'OVERVIEW'">
      <ab-testing-overview-component></ab-testing-overview-component>
    </div>
    <div ng-show="$ctrl.tabData.selectedTab === 'ADS'">
      <ab-testing-details-component></ab-testing-details-component>
    </div>
  </div>
</div>

Im obigen Template sieht man gut, wie auf die einzelnen Child-Komponenten verwiesen wird, welche wiederum aus den entsprechenden Elementen (Metadaten, Controller und Template) bestehen.

Der fehlende Component-Router
Im obigen Code erkennt man wie die einzelnen Komponenten ein- und ausgeblendet werden — mittels ng-show. Dies ist definitiv nicht der perfekte Ansatz. Da wir in unserer Anwendung nicht den UI-Router einsetzen, ist es aktuell nicht möglich die Komponenten ins Routing miteinzubeziehen. Es gab in Angular 1.x das Vorhaben ‘Component Router’ , welches aber deprecated ist und AngularJS auf den ui-router verweist.

Retrospektive

Besonders bei der Frontend-Entwicklung muss man aufpassen, dass die eingesetzten Frameworks sowie die unterstützenden Tools nicht plötzlich als ‘deprecated ‘ markiert sind und anschliessend nicht mehr von der Community unterstützt werden. Deshalb ist eine wichtige gemeinsame (!) Team-Aufgabe, das Auflisten, Beobachten und Bewerten von technischen Schulden. Angular 1.5.x kann ebenfalls bereits in diese Liste aufgenommen werden; muss aber für den eigenen Case detailliert analysiert und bewertet werden. Entsprechende Massnahmen können eine sogn. ‘Big Bang’ Migration oder eine sanfte Migration sein. So oder so müssen Vorarbeiten geleistet werden, wie z.B. der Einsatz von Typescript, die Evaluierung und der Einsatz eines Module-Loaders sowie u.U. die erste Umsetzung von sogn. ‘Components’ in Angular 1.5.x.

Hast Du bereits Erfahrungen mit der Migration gemacht? Hast Du eine Lösung für das oben genannte Problem (Component Router)? Diskutiere mit! Ich würde mich freuen.

Veröffentlicht von

Patrick Roos

Patrick Roos

Mag den stetigen Wandel in der Software-Entwicklung und ist immer wieder im Squash-Court anzutreffen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.