1. Introduction
Le langage TypeScript est un surensemble typé de JavaScript dont la philosophie n'est pas de remplacer JavaScript, mais de se poser en véritable complément.
Pour illustrer ce propos, regardons comment utiliser TypeScript pour monter un petit serveur sous NodeJS.
Le code source de ce projet est disponible sur le dépôt GitHub suivant : https://github.com/yahiko00/SimpleNodeApp
2. Mise en place de l'environnement de travail
Pour cet article, l'environnement de travail que nous allons mettre en place se compose de trois volets : l'organisation des répertoires, l'installation et la configuration de TypeScript et l'installation de NodeJS.
2.1. Arborescence
Projet/
build/ ...
node_modules/ ...
src/
index.html
tsconfig.json
node_modules/ ...
src/
server.ts
index.html
tsconfig.json
Le répertoire Projet/ constituera la racine du projet où on trouvera les fichiers index.html, notre page Web, et tsconfig.json que nous verrons plus en détail un peu plus loin ; le répertoire build/ sera là où sera généré le résultat de la compilation de TypeScript ; le répertoire node_modules/, généré par l'utilitaire npm, contiendra le "liant" entre TypeScript et NodeJS ; et le répertoire src/ contiendra nos scripts.
2.2. TypeScript
Nous travaillerons avec la version 2.0 de TypeScript qui est actuellement en mode beta au moment où est écrit cet article. Pour l'installer, voici la ligne de commande :
npm install typescript@beta -g
Par la suite, lorsque cette version 2.0 (ou ultérieure) sera en production, il suffira de taper cette ligne de commande pour installer TypeScript :
npm install typescript -g
La configuration du compilateur TypeScript peut s'effectuer à différents endroits. Au niveau de l'EDI comme c'est le cas pour Visual Studio par exemple, au niveau de la ligne de commande avec les options de compilation ou au niveau d'un fichier projet qui se nomme par défaut tsconfig.json. Ce fichier doit se trouver à la racine du projet, dans notre cas Projet/. Un squelette de ce fichier projet peut être généré par le compilateur via la ligne de commande suivante :
tsc --init
Pour les besoins de cet article, voici ce que doit contenir ce fichier :
Code javascript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // tsconfig.json { "compilerOptions": { "noImplicitAny": true, "target": "es5", "module": "commonjs", "outDir": "./build" }, "exclude" : [ "./build", "./node_modules" ] } |
- Dans la section compilerOptions, l'option noImplicitAny indique que les déclarations non typées, comme par exemple let x;, ne seront pas permises.
- L'option target permet de définir la version ECMAScript que doit générer TypeScript. Par défaut, c'est la version ES5.
- L'option module permet de définir le format des modules à gérer par le compilateur aussi bien à l'importation qu'à la génération. Ici nous travaillerons avec le format CommonJS qui est celui de NodeJS, mais les formats AMD, SystemJS, UMD et ES2015 (ES6) sont également supportés.
- L'option outDir définit un répertoire vers lequel seront générés les résultats de la compilation.
- La section exclude définit les répertoires et les fichiers à exclure du projet. Ici, on souhaite ignorer les fichiers se trouvant dans le répertoire de sortie build/ et les bibliothèques rapatriées via npm qui se retrouveront dans le répertoire node_modules/.
Pour avoir la liste exhaustive des options disponibles dans tsconfig.json, on peut simplement afficher l'aide du compilateur via la commande tsc -h, dans la mesure où tsconfig.json reprend toutes les options du compilateur, à de rares exceptions près. On peut également se reporter à la page suivante, même si sa mise à jour est souvent en décalage avec la dernière version de TypeScript.
2.3. NodeJS
Si ce n'est pas déjà fait, il convient d'installer NodeJS en le téléchargeant au lien suivant : https://nodejs.org/en/download/
Afin que TypeScript puisse correctement exploiter l'API de NodeJS écrite en JavaScript, il est nécessaire de lui fournir un fichier de définitions de types au format .d.ts. Heureusement, pour la plupart des bibliothèques et frameworks un minimum diffusés, il existe de tels fichiers de définition prêts à l'emploi. Grâce à la version 2.0, une simple commande npm suffit à rapatrier le fichier de définition dont nous avons besoin :
npm install @types/node
Cela téléchargera le fichier de définition de types .d.ts pour NodeJS dans le répertoire standard Projet/node_modules/@types/. Si notre éditeur exploite correctement la fonctionnalité de découverte automatique des fichiers de définitions de types fournie par l'API du compilateur, et c'est le cas notamment pour Visual Studio et Visual Studio Code, alors nous n'avons rien d'autre à faire pour utiliser NodeJS dans notre projet TypeScript.
Maintenant que notre environnement de travail est prêt, voyons à quoi ressemble le code.
3. Serveur NodeJS minimaliste
Notre serveur NodeJS se contentera du minimum. Il traitera n'importe quelle requête de la même façon en affichant le contenu de la page HTML index.html. Ce n'est évidemment que juste pour l'exemple.
Code html : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | <!DOCTYPE html> <html> <meta charset="utf-8"> <head> <title>Simple nodeJS application in TypeScript</title> </head> <body> <h1>Simple nodeJS application in TypeScript</h1> </body> </html> |
Voici le programme principal NodeJS :
Code typescript : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // server.ts import http = require('http'); import os = require('os'); import fs = require('fs'); class HttpServer { nodePort: number; constructor (port: number) { this.nodePort = port; } onRequest(request: http.ServerRequest, response: http.ServerResponse) { console.log('New request: ' + request.url); fs.readFile('./index.html', (err: Error, data: Buffer) => { if (err) { throw err; } response.writeHead(200, {'Content-Type': 'text/html'}); response.write(data); response.end(); }); } onStart() { let httpServer = http.createServer(this.onRequest); httpServer.listen(this.nodePort); console.log('Server listenning on http://' + os.hostname() + ':' + this.nodePort + '/'); } } let server = new HttpServer(8080).onStart(); |
On peut constater que le code est compréhensible au premier coup d’œil au point qu'on peut sans problème se passer de commentaires. L'organisation en classe permet de connaître rapidement les fonctionnalités disponibles et le typage permet de savoir ce qui est passé en paramètre des méthodes.
L'importation des modules externes est fait avec la syntaxe TypeScript import variable = require('module') d'avant la norme ES2015, qui sera simplement transpilée au format CommonJS en var variable = require('module').
La classe HttpServer possède un constructeur qui initialise l'attribut nodePort qui sera le port d'écoute du serveur Node.
Cette classe possède deux méthodes : onRequest() et onStart(). La méthode onRequest() a pour tâche d'envoyer au client le contenu du fichier HTML index.html, et ce de façon inconditionnelle, sans tenir compte du type de requête reçue.
La méthode onStart() quant à elle lance le serveur sur le port défini via le constructeur. Elle est d'ailleurs appelée juste après l'instanciation de la classe HttpServer, à la dernière ligne.
Après avoir compilé avec la commande tsc, il ne reste plus qu'à lancer le programme avec la commande suivante à la racine du projet :
node ./build/server.js
Et sur notre navigateur, à l'adresse suivante, http://localhost:8080/, nous devrions voir apparaître notre page index.html.
4. Conclusion
Voià ! Comme on vient de le voir, utiliser NodeJS avec TypeScript est très simple. Tant dans la mise en place de l'environnement que dans l'écriture du code. Bien entendu, l'exemple que nous venons de voir peut largement être amélioré, mais la façon d'utiliser TypeScript avec NodeJS ne devrait pas fondamentalement changer.
Si vous avez trouvé ce billet utile, n'hésitez pas à le partager.
Bon développement !