Suche
Plug-in von Everlaw macht NetBeans für TypeScript fit

TypeScript, Angular 2, NetBeans IDE: Ein unschlagbares Trio

Karsten Sitterberg

© Shutterstock.com/Morrowind

Nachdem Angular 2 nun in der Beta-Phase angekommen ist und die Stabilität der API gewährleistet sein sollte, ist es Zeit, sich das Framework etwas genauer anzuschauen. Dank eines Plug-ins ist es nämlich nun möglich, TypeScript in der NetBeans IDE zu verwenden.

Angular 2 unterstützt verschiedene Sprachen: Dart, TypeScript, ECMAScript 2015 und ES5, also klassisches JavaScript. Dieser Artikel widmet sich vor allem der Umsetzung von Angular 2 mit TypeScript, da Angular 2 primär auf TypeScript basierend entwickelt wurde, was Vorteile in der Entwicklung gegenüber klassischem JavaScript und auch ECMAScript2015/ES6 bietet.

Neuigkeiten in Angular 2

Eine wesentliche Änderung im Gegensatz zu Angular 1.x ist die Verwendung von Components anstelle von Direktiven mit Controllern.
Weiterhin wurde der Digest-Cycle von Angular 1, der auf Dirty-Checking beruhte, gegen einen Change-Detection-Algorithmus ausgetauscht, der Änderungen am DOM in einem Durchlauf erkennt. Anders als bisher wird damit serverseitiges Rendering möglich, da feststeht, wann alle Änderungen verarbeitet sind. Zudem verspricht dieses Design deutliche Geschwindigkeitsvorteile bei vielen gleichzeitigen Komponenten auf einer Webseite.

W-JAX
Christian Schneider

Schlimmer geht immer – eine Auswahl der Top-10-Hacks der letzten Jahre

mit Christian Schneider (Christian Schneider IT-Security)

NetBeans und TypeScript

NetBeans hat sehr überraschend TypeScript-Support erhalten, nämlich in Form einer Community-Contribution: Die Firma Everlaw hat das von ihr entwickelte NetBeans-Plug-in kurzerhand open source verfügbar gemacht – seitdem gibt es eine kontinuierliche Weiterentwicklung, wie man der GitHub-Seite der Releases entnehmen kann.

image 1

Um TypeScript in NetBeans nutzen zu können, verwendet man am besten die aktuelle NetBeans Version 8.1 (HTML5 Edition oder All), die man auf der Seite von NetBeans herunterladen kann.
Danach wird das oben beschriebene Everlaw-Plug-in als NBM-Datei von GitHub heruntergeladen.

Die Datei wird über den Plug-in-Manager von NetBeans installiert (ToolsPlugins und dort unter dem Reiter DownloadedAdd Plugins das TypeScript-NBM hinzufügen und installieren).

image 2
image 3

Benötigte Software

Bei JavaScript-Entwicklung sind viele Werkzeuge selbst in JavaScript geschrieben. Diese werden mit Hilfe von Node.js ausgeführt. Für JavaScript-Libraries und -Module ist der Node-Package-Manager zuständig, kurz „NPM“. Die Installation von Node.js und NPM kann auf einem Linux-System in der Regel durch den jeweiligen Paketmanager erfolgen. Dabei kann dann auch curl installiert werden, falls es noch nicht vorhanden ist. Bei Ubuntu könnte das dann so aussehen:

sudo apt-get install nodejs npm curl

Die Einrichtung in NetBeans ist denkbar unkompliziert. Bei den Einstellungen (ToolsOptions) wählt man HTML5/JS und klickt sowohl bei „Node Path“ als auch bei „npm Path“ auf den „Search“-Button. Anschließend sollten beide Werkzeuge erkannt werden.
Damit der NetBeans-Support für Node.js optimal funktioniert, müssen noch die Node.js-Sources heruntergeladen werden. Dazu wählt man einfach den „Download“-Button im Node.js-Abschnitt.

image 4

Setup des Angular2-Projektes in NetBeans

Das Setup des Projektes erfolgt, wie bei jedem gewöhnlichen NetBeans-Projekt. Zunächst wird der „New Project“-Dialog aufgerufen; in der Kategorie „HTML5/JavaScript“ wird dann ein neues Projekt in Form einer „HTML5/JS-Application“ angelegt.

image 5

Nach einem Klick auf den „next“-Button können noch der Name und der Zielordner für das Projekt ausgesucht werden und in einem weiteren Schritt können Templates hinzugefügt werden. Dieser Schritt wird aus Gründen der Einfachheit hier jedoch übersprungen.
Im letzten Schritt wählt man „next“, aber noch nicht „finish“ aus, sodass man die folgenden Konfigurationsdateien durch NetBeans erzeugen lassen kann:

  • package.json (bower.json, wenn statt NPM bower verwendet wird)

Analog zum Angular-Tutorial auf angular.io wird in diesem Beispiel NPM zum Managen der Dependencies verwendet.
Anschließend legt man die Abhängigkeiten von Angular 2 in der package.json an.

{
	"name": "2016-01-angular2-simple",
	"version": "1.0.0",
	"keywords": ["util", "functional", "server", "client", "browser"],
	"author": "Karsten Sitterberg",
	"scripts": {
    	"tsc": "tsc",
    	"tsc:w": "tsc -w",
    	"lite": "lite-server",
    	"start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
	},
	"dependencies": {
    	"angular2": "2.0.0-beta.2",
    	"systemjs": "0.19.6",
    	"es6-shim": "^0.33.3",
    	"reflect-metadata": "0.1.2",
    	"rxjs": "5.0.0-beta.0",
    	"zone.js": "0.5.10"
	},
	"devDependencies": {
    	"concurrently": "^1.0.0",
    	"lite-server": "^1.3.1",
    	"typescript": "^1.7.3"
	}
}

Die einzelnen Komponenten sind dabei:

RxJS Liefert Observables für asynchrone, Event-basierende Programmabläufe
zone.js Liefert Execution-Contexts für asynchrone Tasks, wird zum Updaten der View benutzt
SystemJS Module Loader (Angular 2 besitzt, im Gegensatz zu Angular 1, keinen eigenen)
ES6-shim Ermöglicht das Verwenden von ES6-Funktionen, auch in Browsern ohne ES6-Support
reflect-metadata Ermöglicht Dependency-Injection durch Decorators
typescript Transpiler, überzetzt TypeScript nach JavaScript
lite-server Ein leichtgewichtiger File-Server, der während des Entwicklungs-Prozesses genutzt werden kann
concurrently Zum plattformunabhängigen, parallelen Ausführen mehrerer Prozesse

Direkt aus NetBeans heraus lassen sich die Abhängigkeiten nun installieren – eine funktionierende Internetverbindung vorausgesetzt. Dazu wählt man nach einem Rechtsklick auf das Projekt den Punkt „npm install“ innerhalb des Kontextmenüs aus.

Damit das Projekt direkt im Browser ausgeführt werden kann, sollte man NetBeans noch mitteilen, welchen Browser es dafür nutzen soll. Dies wird in der oberen Symbolleiste gemacht. Mit einem Klick auf das Browsersymbol klappt sich ein Menü auf, in dem ein einfacher Chromium ausgewählt werden kann.

image 6

Initialisierung TypeScript Compiler

Um das Transpilieren von TypeScript nach ES5 zu ermöglichen, wird eine Konfiguration in Form einer JSON-Datei tsconfig.json benötigt, welche neben der Datei package.json in der Site-Root abgelegt werden sollte. Dazu ist es sinnvoll, das Projekt vorher mit NetBeans so zu konfigurieren, dass die Orte von Project-Root mit der Site-Root übereinstimmen. Dies geschieht per Rechtsklick auf das Projekt und Auswahl des „Properties“-Eintrags. Im Properties-Menü wird der Eintrag für die Site-Root entsprechend auf einen leeren Wert gesetzt.

image 7

Weiterhin sollte im Unterpunkt „JavaScript Frameworks“ → „Typescript“ die Option „Compile on Save“ ausgewählt werden, damit nach jedem Speichervorgang die Übersetzung zu JavaScript stattfindet.

image 8

Der Inhalt der tsconfig.json sieht dann folgendermaßen aus:

{
  "compilerOptions": {
	"target": "ES5",
	"module": "system",
	"moduleResolution": "node",
	"sourceMap": true,
	"emitDecoratorMetadata": true,
	"experimentalDecorators": true,
	"removeComments": false,
	"noImplicitAny": false
  },
  "exclude": [
	"node_modules"
  ]
}

Die einzelnen Optionen bedeuten dabei:

target Zielsprache, hier ES5, also „Standard JavaScript“
module Gibt an, welcher Standard bei der Modul-Generation verwendet werden soll
moduleResolution Bestimmt, wie Module-Namen aufgelöst werden (in diesem Fall ähnlich konfiguriert zu Node.js)
sourceMap Erzeugt eine Datei, die eine Beziehung zwischen Quellcode und Ergebnis herstellt. Wird vor allem beim Debugging genutzt.
emitDecoratorMetadata Übertragen von Design-Typen in Decorator-Deklarationen
experimentalDecorators Deaktiviert die Warnung, dass emitDecoratorMetadata eine experimentelle Option ist
noImplicitAny Fehlermeldungen, falls (leere) Zuweisungen oder Ausdrücke mit implizitem „any“-Typ verwendet werden
exclude Verhindert, dass Dateien kompiliert werden, in diesem Fall ist es zum Beispiel nicht nötig, die per NPM installierten Dependencies (node_modules) zu kompilieren.

Grundlagen Angular 2

Angular 2 dient dem Erstellen von performanten HTML5/JavaScript-Applikationen. Angular 2 baut auf verschiedenen JavaScript-Bibliotheken, wie RxJs oder zone.js auf und bietet eine neue Abstraktionsschicht, um eigene Komponenten (@Component) und Services (@Injectable) zu erstellen. Services bilden dabei die Logik ab, während die Applikation an sich in Form von Komponenten verwaltet wird.
Dem Entwickler bietet Angular 2 eine hohe Flexibilität in Hinblick auf die verwendete Technologie; Applikationen können in TypeScript, Dart oder nativem JavaScript (ES5- und auch ES6-Standard) implementiert werden. In diesem Artikel wird die TypeScript-Variante verwendet, um die Funktionalität von NetBeans in Verbindung mit dem Everlaw- / nbts-TypeScript-Plug-in darzustellen.
Eine grundlegende Angular 2-Anwendung wird wie eine normale HTML-Seite ausgeliefert. Diese Seite enthält dann den Aufruf an Angular 2, mit dem das Kompilieren und Rendern der Root-Komponente und damit der Anwendung gestartet wird.

Beispielprojekt

In unserem Beispielprojekt erstellen wir eine Angular 2-Komponente, die bewusst einfach gehalten ist, um den Fokus auf die notwendigen Schritte und die Nutzung der NetBeans IDE zu legen. Als Anwendungsfall wurde daher eine einfache Komponente gewählt, die einen Namen anzeigen kann, der in das Input-Feld eingegeben wird. Außerdem ist ein Button vorhanden, mit dem man die Ausgabe des Namens ein- und ausschalten kann.
Bei Ausfüllen der Input-Box fällt direkt das reaktive Verhalten von Angular 2 auf: Jeder eingegebene Buchstabe erscheint direkt in der Ausgabezeile darüber.

image 9image 10

Durch einen Klick auf den entsprechenden Button kann die Ausgabezeile ein- und ausgeblendet werden. Hierbei bleibt der Inhalt des Input-Feldes mit dem Zustand der Anwendung verbunden, sodass ein erneuter Klick auf den Button den Namen (und eventuell daran vorgenommene Änderungen) sichtbar macht.

image 11

Struktur

projectRoot/		- index.html
					- package.json
					- tsconfig.json
					- app/
						- boot.ts
						- simple.component.ts
					- node_modules/

Das Projekt enthält neben den node_modules, die durch den Aufruf von “npm install” erzeugt wurden, den app-Ordner, in dem die Anwendungslogik vorhanden ist. Die Datei “boot.ts” enthält die Anweisungen zum Bootstrappen der Anwendung und die Datei “simple.component.ts” stellt die eigentliche Komponente bereit.
Die “index.html” wird im Wesentlichen nur benötigt, um dem Browser mitzuteilen welche node_modules er laden muss und wie die JavaScript-Umgebung zu konfigurieren ist. Außerdem wird dort die App gestartet, indem die Komponente im HTML-Body platziert wird. Hierbei kommt es vor, dass NetBeans die selbst angelegte Komponente nicht als eigenes HTML-Element erkennt. Dann werden aufgrund des strikten internen HTML-Validators Warnungen oder Fehlermeldungen für das öffnende Tag der Komponente einblendet.

index.html:

<html>
   <head>
    	<title>Simple Angular 2 App</title>

      <!-- 1. Load libraries -->
      <script src="node_modules/es6-shim/es6-shim.js"></script>
      <script src="node_modules/angular2/bundles/angular2-polyfills.js">
</script>
      <script src="node_modules/systemjs/dist/system.src.js"></script>
      <script src="node_modules/rxjs/bundles/Rx.js"></script>
      <script src="node_modules/angular2/bundles/angular2.dev.js"></script>

      <!-- 2. Configure SystemJS -->
      <script>
         System.config({
            packages: {
               app: {
                  format: 'register',
                  defaultExtension: 'js'
               }
    	      }
         });
         System.import('app/boot').then(null, console.error.bind(console));
      </script>
      </head>

      <!-- 3. Display the application -->
      <body>
            <simple-component>Loading...</simple-component>
      </body>
</html>

Zum Laden der Anwendung wird, nach dem entsprechenden Import, die „bootstrap“-Funktion aufgerufen, die die zu ladende Komponente übergeben bekommt (auch diese muss natürlich importiert werden).

boot.ts:

import {bootstrap}	from 'angular2/platform/browser'
import {SimpleComponent} from './simple.component'

bootstrap(SimpleComponent);

Komponenten werden in TypeScript durch Klassen abgebildet. Dabei steckt die Logik in den Methoden und Properties der Klasse. Allerdings ist zu beachten, dass nicht automatisch jede Klasse eine Komponente ist, da zum Beispiel auch Services durch Klassen abgebildet werden. Um Angular mitzuteilen, dass es sich bei dieser speziellen Klasse um eine Komponente handelt, wird die @Component-Annotation verwendet. In ihr findet die Konfiguration der Komponente statt. Zum Beispiel wird hier der Selektor angegeben, durch den die Komponente hinterher aus dem HTML-Dokument heraus aufgerufen werden kann. Weiterhin wird hier das Template spezifiziert, also die Ausgabe – die „View“ – der App. Im Template können sowohl die typischen HTML-Elemente wie „<h1>“, die typischen Angular 2 Property- und Event-Bindings (z.B. [hidden], (click)) als auch selbst erstellte Komponenten verwendet werden.

simple.component.ts:

import {Component} from "angular2/core"

@Component({
	selector: "simple-component",
	template: `
    	<h1>Hallo Angular 2!</h1>
    	<div>
        	<label [hidden]="!isCalling">Ich bin {{name}}.</label>
        	<div>
            	<input [(ngModel)]="name" />
            	<button (click)="toggleCalling()">toggle Calling</button>
        	<div>
    	</div>
    	`
})
export class SimpleComponent {
	private name = "da";
	private isCalling = true;

	private toggleCalling() {
    	this.isCalling = !this.isCalling;
	}
}

In diesem Fall wird das hidden-Property des Labels mit Hilfe der Variablen isCalling geschaltet, wodurch es je nach Zustand der Variablen ein- und ausgeblendet wird. Der Zustand dieser Variablen kann mit einem Klick auf den Button verändert werden, da an das Onclick-Event des Buttons der toggleCalling()-Callback gebunden ist.
Das Property „name“ wird durch Two-Way-Binding an den Wert des Input-Elements gebunden. Im Label wird es dann durch die von Angular benutzte Interpolations-Syntax ausgegeben.

Hilfreiche Features

Um eine Anwendung effektiv entwickeln zu können, ist eine gute Unterstützung des Entwicklers durch die Entwicklungsumgebung nötig. Diese Unterstützung wird in NetBeans durch das Everlaw-Plug-in bereitgestellt. Es beinhaltet zum Beispiel Syntax-Highlighting, Usages-Highlighting, Fehlermarkierung und Code-Completion für TypeScript. In den Bildern sind zum Beispiel alle Verwendungen des this-Arguments gehighlighted. Usage-Highlighting wird durch das Plug-in automatisch für jede markierte Variable durchgeführt. Im oberen Bildabschnitt wird versucht, einen nicht existierenden Import durchzuführen. NetBeans erkennt sowohl, dass im Pfad “angular2/core” nichts mit dem Namen „Component“ vorhanden ist, als auch, dass die „@Component“-Annotation nicht korrekt importiert wurde.

image 12

Die Code-Completion wird durch das von NetBeans gewohnte Shortcut (Crtl+Space) ausgelöst.

image 13

Weiterhin wird jede TypeScript-Datei von NetBeans automatisch transpiliert, sobald die Datei gespeichert wird. Sollen alle Dateien komplett neu transpiliert werden, so kann dies auch durch das Entsprechende NPM-Script geschehen, welches von NetBeans aufgerufen werden kann. Dafür ist ein Rechtsklick auf das Projekt nötig, wo das entsprechende Skript ausgeführt wird (in diesem Fall „tsc“).

image 14

Da das Plug-in noch recht jung ist, kann es hin und wieder zu kleinen Problemen kommen. Beispielsweise kann es vorkommen, dass Fehlermarkierungen nicht gelöscht werden, obwohl der Fehler behoben ist. Dies kann mit einem Neustart von NetBeans behoben werden.

Fazit und Ausblick

Angular 2 ist schon in einem sehr gut nutzbaren Zustand. Wer größere Anwendungen plant, sollte sich mit den Themen TypeScript und Angular 2 auf jeden Fall befassen und sich über Schulungen mit relevanten Architekturkonzepten vertraut machen.
NetBeans ist dank des TypeScript-Plug-ins und der bestehenden Infrastruktur sehr gut als integriertes Werkzeug zur Entwicklung von Angular 2 Frontend-Anwendungen geeignet.
Grundlegende Features wie Syntax-Highlighting oder Code-Completion sind genauso enthalten wie das automatische Transpilieren von TypeScript nach JavaScript beim Speichern einer Datei. Aufgrund des noch recht jungen Plug-ins treten noch kleine Schönheitsfehler auf, die aber sicherlich in zukünftigen Versionen behoben werden. Dazu kann auch der geneigte Entwickler beitragen, zum Beispiel in Form von Pull-Requests auf GitHub.

Aufmacherbild: web site codes macro von shutterstock.com / Urheberrecht: Morrowind

Geschrieben von
Karsten Sitterberg
Karsten Sitterberg
Karsten Sitterberg ist als freiberuflicher Entwickler, Trainer und Berater für Java und Webtechnologien tätig. Karsten ist Physiker (MSc) und Oracle-zertifizierter Java Developer. Seit 2012 arbeitet er mit trion zusammen.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.