Tutorial on how you can create an app with TypeScript and Node.js, using Gulp to automate the building process and Nodemon to restart the server.
TypeScript is a free open-source programming language developed and maintained by Microsoft. It is a strict superset of JavaScript and adds optional static typing and class-based object-oriented programming to the language. Today we are going to learn how to use TypeScript with Node.js.
We will be building a simple Hello world
application, which shows the current date and time using TypeScript and Node.js.
While there are lots of reasons why you should use TypeScript, here are three which I think are convincing enough.
var me = "myname"
In the code above, we leave it to the interpreter to guess which data type the variable is. In TypeScript, we can declare the same variable as:
var me: string = "my name"
This gives the option of declaring what data type we want, which also helps while debugging.
Let’s take a look at this example:
1interface Usercheck{ 2 name: string; 3 age: int; 4 } 5 6 class User implements Usercheck { 7 constructor (public name: string, public age: int) { 8 } 9 }
The User class obeys, and must have data-types and definitions to, the interface Usercheck
because it implements Usercheck
. This is a function that is usually appreciated more by developers who use static languages.
1//Typescript 2 class Test { 3 //field 4 name:string; 5 //constructor 6 constructor(name:string) { 7 this.name = name 8 } 9 //function 10 display_name():void { 11 console.log("name is : "+this.name) 12 } 13 } 14 //javascript 15 var Test = (function () { 16 //constructor 17 function Test(name) { 18 this.name = name; 19 } 20 //function 21 Test.prototype.display_name = function () { 22 console.log("name is : " + this.name); 23 }; 24 return Test; 25 }());
In the snippet above, notice that it is easier to read the TypeScript version of the code than the JavaScript Version. In the TypeScript version, we can immediately see that the public variable called name
is of the string data-type. In the JavaScript version, we cannot immediately figure out the data-type of the variable. Also, in the JavaScript Version, we had to use the prototype
function to declare our display_name
function, while in TypeScript we did not have to do that.
To install TypeScript globally so you can call it when needed, run:
npm install -g typescript
For verification of the installed TypeScript, use the tsc --v
command:
1tsc --v 2 //Version 2.1.6
Next, install gulp
for the build process. To do that, run:
npm install -g gulp
Now, create a folder that will hold the application. To do this, run npm init
and follow the instructions below:
1//create a new directory 2 mkdir type-node 3 //change directory to the new folder 4 cd type-node 5 //run npm init 6 npm init
You should now have all the basic libraries to start configuring for use.
Given no arguments, tsc
will first check tsconfig.json
for instructions. When it finds the config, it uses those settings to build the project.
Create a new file called tsconfig.json
in the root folder and add the following:
1{ 2 "compilerOptions": { 3 "target": "es6", 4 "module": "commonjs" 5 }, 6 "include": [ 7 "**/*.ts" 8 ], 9 "exclude": [ 10 "node_modules" 11 ] 12 }
This defines the three major sections, which include compilerOptions
, include
and exclude
parameters:
index.ts
file in the root, and run tsc on the command line, we will see the compiled **index.js**
file.Although we have installed Gulp globally, we still need to install Gulp in our local project as well as Gulp-TypeScript. To do that, we run:
npm install gulp gulp-typescript typescript --save
Doing just this setup done might be enough, but you would have to go back to the terminal to run the tsc
command every time a change occurs. Instead, you can use Gulp to automate the process and run the compilation each time you change the file. Here’s how.
Add a gulpfile.js
to the root of the directory. This enables automatic compilation of the source files. Now, put the following contents into the gulpfile.js
:
1const gulp = require('gulp'); 2 const ts = require('gulp-typescript'); 3 4 // pull in the project Typescript config 5 const tsProject = ts.createProject('tsconfig.json'); 6 //task to be run when the watcher detects changes 7 gulp.task('scripts', () => { 8 const tsResult = tsProject.src() 9 .pipe(tsProject()); 10 return tsResult.js.pipe(gulp.dest('')); 11 }); 12 //set up a watcher to watch over changes 13 gulp.task('watch', ['scripts'], () => { 14 gulp.watch('**/*.ts', ['scripts']); 15 }); 16 17 gulp.task('default', ['watch']);
This creates a Gulp task which fires once a watcher triggers. A Gulp watcher watches for changes in the ts files and then compiles to JavaScript.
Now, delete the index.js
file the tsc
command created earlier. If you run Gulp, you will notice that the index.js file is re-created and that Gulp is now watching for changes.
Now that the Gulp watcher is running on one terminal, move to another terminal and continue the configuration.
Creating The App.ts File
First, we need to install the Express
library by running the following:
npm install express --save
The next step is to create the app.ts file that holds the Express app. Create an app.ts file, and copy the following into it:
1import * as express from 'express'; 2 // Creates and configures an ExpressJS web server. 3 class App { 4 // ref to Express instance 5 public express: express.Application; 6 //Run configuration methods on the Express instance. 7 constructor() { 8 this.express = express(); 9 this.middleware(); 10 this.routes(); 11 } 12 // Configure Express middleware. 13 private middleware(): void { 14 } 15 16 // Configure API endpoints. 17 private routes(): void { 18 /* This is just to get up and running, and to make sure what we've got is 19 * working so far. This function will change when we start to add more 20 * API endpoints */ 21 let router = express.Router(); 22 // placeholder route handler 23 router.get('/', (req, res, next) => { 24 res.json({ 25 message: 'Hello World!' 26 }); 27 }); 28 this.express.use('/', router); 29 } 30 } 31 export default new App().express;
This has imported everything from Express and created a TypeScript class called App
. A public property called express was also declared. Additionally, in the constructor, we had assigned an instance of the Express
library to a public property called express
which we defined earlier.
Finally, the middleware and routes function are being called. The middleware function defines middleware like CORS, templating engine, etc, while the routes function registers the routes, which have been set.
Next, we will create an Express entry point, which we will write in TypeScript.
Create a new file called main.ts
and add the following to it:
1import * as http from 'http'; 2 import App from './App'; 3 const port = 3000; 4 App.set('port', port); 5 //create a server and pass our Express app to it. 6 const server = http.createServer(App); 7 server.listen(port); 8 server.on('listening', onListening); 9 10 //function to note that Express is listening 11 function onListening(): void { 12 console.log(`Listening on port `+port); 13 }
This has imported the HTTP module from node. The App
class which runs the application is being imported.
Get a port value from the environment or set the default port number to 3000. Create the HTTP server, and pass App
to it (Express app). Set up some basic error handling and a terminal log to show when the app is ready and listening.
If you run node main.js
in the terminal, you will get a message that says listening on port 3000
Go to your browser, and you should see something like this:
Creating the **npm test**
command
Inside our package.json
file, let’s replace the part that defines the script section with the following:
1"scripts": { 2 "test": "gulp" 3 }
Now, any time we run npm test
our Gulp
command will run.
Notice that when you run npm test
, it runs the Gulp watch script, and errors like “*****can not find some modules*****” might pop up. This is because TypeScript needs some definitions before it can read raw node libraries.
To install TypeScript definitions, use the @types
notation with the packages. That is, to install Express TypeScript definitions, you will run npm install @types/express
, but all the packages have already been installed, so we will install only the node
types definition.
Open up the terminal and do this:
npm install @types/node --save
If you now run the npm test
, error messages will have cleared up and scripts will re-compile on the go, however make sure you restart the server to check that the error messages do not show up anymore.
To allow the server to refresh the changes on the go, use nodemon
. Nodemon is an npm package that restarts the server any time application files change.
Install Nodemon:
npm install -g nodemon
Once Nodemon has finished installing, instead of node main.js
, run nodemon main.js
. Change what shows on the browser from the simple JSON message to a couple of HTML tags, and go to the routes
function in the app``**.ts**
file to move the part where res.json
appears on line 30, and change the whole block to this:
1res.send( 2 `<html> 3 <head> 4 <title>Tutorial: HelloWorld</title> 5 </head> 6 <body> 7 <h1>HelloWorld Tutorial</h1> 8 9 <p> 10 The current data and time is: 11 <strong>`+new Date()+`</strong> 12 </p> 13 14 </body> 15 </html>` 16 )
That is it! You have created your first Express application using TypeScript.
Following the tutorial, you should have created your first simple application using TypeScript and Node.js. In summary, you should have learned how to use Gulp to automate the building process, as well as using Nodemon to restart the server. Once the scripts have re-compiled, you can decide to add more things like using view engines, serving static files, performing file uploads and a lot more.
The code base to this tutorial is available in a Public Github Repository. You can clone the repository and play around with the code base.