© best_vector/Shutterstock.com
Teil 5: TypeScript - Module

Mit Modulen optimal strukturieren


Bisher wurde in dieser Artikelserie der TypeScript-Code immer in einer einzigen .ts-Datei platziert. Doch beim Entwickeln einer größeren Anwendung lässt sich Code in einer einzigen Datei sehr schlecht warten. Daher unterstützt TypeScript sogenannte Module, die das Strukturieren und Organisieren über separate .ts-Dateien hinweg erlauben. Dieser Artikel zeigt, was es genau mit Modulen auf sich hat und wie ein Module Bundler eingesetzt wird, damit die einzelnen TypeScript-Dateien für eine Web-App zu einer einzigen JavaScript-Datei kompiliert werden können.

Module sind dabei kein von TypeScript eingeführtes Konzept, sondern Bestandteil des ES2015-Standards. Sie erlauben das Strukturieren und Organisieren des eigenen TypeScript-Codes über mehrere Dateien hinweg. Dabei ist ein Modul lediglich eine .js-Datei bzw. im Fall von TypeScript eine .ts-Datei, die mindestens einen Import oder einen Export auf oberster Ebene der Datei hat. Das klingt doch recht simpel. Jede .ts-Datei wird somit als Modul bezeichnet, sobald darin beispielsweise eine Klasse exportiert wird. Doch wozu exportieren? Module erlauben, den TypeScript-Code in einzelne Dateien aufzuteilen. Doch darüber hinaus hat jede TypeScript-Datei bzw. jedes Modul auch noch seinen eigenen Bereich, in dem Klassen, Funktionen und Variablen sichtbar sind. Das bedeutet, diese Komponenten sind nur für das Modul selbst sichtbar. Dieses Merkmal von Modulen ist insbesondere in größeren Projekten sehr hilfreich, da sich dadurch z. B. derselbe Funktionsname in verschiedenen Modulen verwenden lässt, ohne dass es zu Problemen kommt.

Doch wenn jedes Modul seinen eigenen Bereich hat, wie lässt sich dann beispielsweise eine in einem Modul definierte Klasse in einem anderen Modul verwenden? Dazu muss die Klasse aus dem Modul, in dem sie definiert ist, explizit exportiert werden. Doch dies alleine reicht noch nicht: In das Modul, in dem die Klasse verwendet werden soll, muss sie explizit importiert werden. Dabei sieht die zum Importieren und Exportieren notwendige Syntax in TypeScript ganz genauso aus wie in ES2015.

Import und Export

Die friends.ts-Datei in Listing 1 enthält die Friend-Klasse mit den beiden Parameter-Properties firstName und lastName. Vor der Klasse steht das export-Schlüsselwort. Das bedeutet, dass die Friend-Klasse aus dieser TypeScript-Datei exportiert wird. Und da diese Type­Script-Datei jetzt einen Export hat, wird sie als Modul bezeichnet.

Listing 1: „friends. ts“

export class Friend { constructor(public firstName: string, public lastName: string) { } }

Listing 2 zeigt die Datei main.ts. Darin wird die Friend-Klasse aus der friends.ts-Datei importiert und anschließend verwendet. Es wird eine Friend-Instanz erstellt und die Werte der Properties firstName und lastName werden an der Konsole des Browsers ausgegeben.

Listing 2: „main.ts“

import { Friend } from './friends'; let friend = new Friend("Thomas","Huber"); console.log(friend.firstName); console.log(friend.lastName);

Wie bereits erwähnt, verwendet TypeScript die ES2015-Syntax zum Importieren und Exportieren. Bei der Importsyntax erfolgt nach dem from-Schlüsselwort die Angabe der Datei, aus der importiert wird. In Listing 2 ist dies die friends.ts-Datei bzw. aufgrund ES2015-Syntaxkompatibilität die friends.js-Datei. Die Dateiendung ist dabei optional, kann aber wie folgt auch angegeben werden:

import { Friend } from './friends.js';

Die Datei, aus der importiert wird, wird immer relativ zum aktuellen Modul angegeben. In Listing 2 wird ein Punkt für das aktuelle Verzeichnis genutzt, und daraus soll die friends.js-Datei genutzt werden. Diese enthält wiederum die Friend-Klasse, die sich auf diese Weise verwenden lässt.

Module Loader und Bundler

Wird der TypeScript-Code aus Listing 1 und 2 kompiliert, entstehen die beiden Dateien friends.js und main.js. Wird die main.js-Datei vom Browser geladen, sollte der Browser die friends.js-Datei ebenfalls nachladen, da die main.js-Datei ja ein Importstatement enthält, das auf die friends.js-Datei zeigt. Diese Funktionalität unterstützen heutige Browser allerdings nicht. Wird der Code dagegen serverseitig in Node.js genutzt, dann funktioniert es, wenn ein Modulformat vorliegt, das Node.js versteht. Dann kann Node.js die entsprechenden abhängigen Dateien automatisch nachladen. Mehr zu Modulformaten gibt es später. Während das Nachladen von Modulen in Node.js funktioniert, klappt es clientseitig in einer Web-App nicht. Hier braucht der Browser Hilfe. Dabei gibt es prinzipiell zwei Möglichkeiten: der Einsatz eines Module Loaders oder der Einsatz eines Module Bundlers.

Ein Module Loader, wie beispielsweise SystemJS, bringt dem Browser bei, wie er die abhängigen Dateien ebenfalls laden kann. Ein Module Bundler dagegen, wie beispielsweise webpack, bündelt vor dem Deployment alle abhängigen Dateien zu einer einzigen Datei, die der Browser selbst verstehen kann. Das heißt, der Module Bundler transformiert den ganzen Code in eine einzige Datei, die ein heutiger Browser ohne zusätzliche Hilfsmittel ausführen kann. Doch was setzt man jetzt ein, einen Module Loader oder einen Bundler?

Bei serverseitigen Anwendungen mit Node.js ist es meist nicht so wichtig, ob noch ein paar kleinere oder größere Dateien von der Festplatte nachgeladen werden müssen. Denn es ist dazu kein HTTP Request nötig, da es ein direkter und somit schneller Zugriff auf die Festplatte ist. Bei einer Webanwendung dagegen ist es umso wichtiger, dieses Nachladen mehrerer Dateien möglichst gering zu halten, da pro Datei ein Request an den Server erfolgt. Werden die ganzen JavaScript-Dateien folglich mit einem Module Bundler zu einer einzigen JavaScript-Datei gebündelt, dann muss der Browser lediglich einen einzigen HTTP Request für diese gebündelte Datei ausführen. Folglich wird die Anwendung schneller geladen....

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

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang