Get started with typescript, express and test


At the end of this post, you will have your web app up and running locally in your dev environment.

Pre-requisites

Before you get started, ensure that you have the following dependencies in place

Lets get started

Create a new folder called nodewebapi, and navigate to it.

mkdir nodewebapi  
cd nodewebapi  

Open the folder in VS Code (or your favorite IDE). Code is a cross platform development environment. It is free, has an amazing community and has great developer productivity features built in.

code .  

Instead of switching back and forth, you can work with the integrated terminal window. You can use the keyboard shortcut

Ctrl + `  

Initiate the local git repo

git init  

VS Code editor with local git repo for NodeWebAPI

You can install all your dependencies via Node Package Manager (NPM). To start with, initiate NPM via

npm init  

Leave the values to defaults. This will result in a package.json file.

{
  "name": "nodewebapi",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

To start with, you need the following dependencies

  • express – minimal and flexible Node.js web application framework
  • body-parser – Node.js body parsing middleware
  • method-override – lets you use HTTP verbs such as PUT or DELETE in places where the client doesn’t support it.
npm install --save express body-parser method-override  

–save option saves the dependencies metadata in package.json

{
  "name": "nodewebapi",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.17.1",
    "express": "^4.15.2",
    "method-override": "^2.3.7"
  }
}

This way, you can get all your dependencies when you do an npm install.

Also, since we are using typescript we need to add it as a dev dependency.

npm install --save-dev typescript  

–save-dev adds a devDependencies section in package.json.

"devDependencies": {
    "typescript": "^2.2.1"
  }

While using typescript, you can get type checks and intellisense by installing the corresponding @types packages.

npm install --save-dev @types/express @types/node  

Now that you have added the package dependencies, it is time to write some code and setup the web server.

Create a new folder called src, and then create a file called app.ts in it.

mkdir src  
cd src  
touch app.ts  

In app.ts, you will write the code that creates the web server.

import * as express from "express";  
import * as bodyParser from "body-parser";  
import * as methodOverride from "method-override";

let app: express.Application = express();  
app.use(bodyParser.urlencoded({ extended: true }));  
app.use(bodyParser.json());  
app.use(methodOverride());

app.get('/', (req, res) => {  
    res.send('Hello World!');
});

export default app;  

This basic code sets up the web server using express. In the base route / you start with responding back Hello World!

You then export the app, so that we can re-use it to host the app (and later test it as well).

To host the web app, lets create a new file called index.ts

touch index.ts  

Here, you can host the web server and wire up the app you created in app.ts

import * as http from "http";  
import * as express from "express";  
import app from "./app";

let port: number = process.env.PORT ? process.env.PORT : 3000;

const server = http.createServer(app);  
server.listen(port);

server.on('error', onError);  
server.on('listening', onListening);

function onError(error: NodeJS.ErrnoException) : void {  
    throw error;
}

function onListening(): void {  
    console.log('Listening on port ' + server.address().port);
}

port exposes the port in which the web server will be hosted. You can pass it a value via the PORT environment variable. By default, port 3000 is used.

http.createServer(app) wires up the app created earlier, and server.listen(port)hosts the web app in the specified port.

You now have everything in place, except that you have everything in typescript. You need to transpile typescript to javascript.

The easiest way to achieve this in VS Code is to use a task runner. You can open the command palette by using the keyboard shortcut Cmd + Shift + P in mac or ‘Ctrl + Shift + P’ in windows. In it, search for task runner.

Configure task runner in VS Code

Typescript task runner in VS Code

Select Typescript -tsconfig.json

This creates a file called tasks.json in .vscode folder. It looks like the following

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "tsc",
    "isShellCommand": true,
    "args": ["-p", "."],
    "showOutput": "silent",
    "problemMatcher": "$tsc"
}

This configures the build command (Cmd + Shift + B keyboard short cut in mac or Ctrl + Shift + B keyboard shortcut in windws) to transpile the typescript to javascript. It will invoke the typescript compiler and follow the configuration options present in a file named tsconfig.json in the root directory.

Note that you have not created a tsconfig.json file. It is time to create one. Navigate to the root directory in the terminal and create a new file.

touch tsconfig.json  

Populate tsconfig.json with the following data.

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "outDir": "dist"
    },
    "include": [
        "src/**/*.ts"
    ],
    "exclude": [
        "node_modules"
    ]
}
  • module specifies the module for code generation. set it to commonjs
  • target specifies the ECMAScript version which the transpiled javascript files should conform to. In this case, set it to es6
  • outDir specifies the directory in which the javascript files should be generated. In this case, set it to dist
  • include specifies the files and folders in which typescript compiler should look source files. All the code you have created so far are in src folder. So, set it to ‘src/**/*.ts’
  • exclude specifies the directories which the compiler should ignore. In this case, you don’t want to look at files which are already packaged. So set it to ‘node_modules’

With tsconfig.json and tasks.json in place, it is time to build. You can use the keyboard shortcut Cmd + Shift + B in mac or Ctrl + Shift + B in windows.

Dist folder containing js files post build

Notice that dist folder is generated and it contains the transpiled js files app.js and index.js.

Update the ‘package.json’ with a start script so that you specify how to run the program. In this example, the starting code is present in dist/index.js. So create a new start script in the scripts section and set its value to node ./dist/index.js

"start": "node ./dist/index.js"

The final package.json will look like the following:

{
  "name": "nodewebapi",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node ./dist/index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.17.1",
    "express": "^4.15.2",
    "method-override": "^2.3.7"
  },
  "devDependencies": {
    "@types/express": "^4.0.35",
    "@types/node": "^7.0.8",
    "typescript": "^2.2.1"
  }
}

You are now all set. Try it out, by running the following command from terminal

npm start  

You will notice that the server is now listening on port 3000

> node ./dist/index.js

Listening on port 3000  

Navigate to http://localhost:3000 in your browser.

Web app running locally in node

Your web app is now running in node. Congratulations!

With the code up and running, it is also time to write tests. Also, with the basics in place, you can now start writing tests first and then writing the code to support those scenarios.

To get started with testing, you can install the following dependencies

  • mocha – a feature-rich JavaScript test framework running on Node.js and in the browser
  • chai – a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework
  • chai-http – HTTP Response assertions for the Chai Assertion Library.
npm install --save mocha chai chai-http  

Also, install the type definition for these libraries as dev dependencies.

npm install --save-dev @types/mocha @types/chai @types/chai-http  

With the libraries in place, you can create a new folder for test in the root directory and create your first test.

mkdir test  
cd test  
touch baseRoute.ts  

In baseRoute.ts, start by importing the test framework modules you just installed.

import * as mocha from "mocha";  
import * as chai from "chai";  
import chaiHttp = require("chai-http");  

You have abstracted the app server in src/app.ts. You need to reference it here, so that you can run your tests against it.

import app from "../src/app";  

You can then use chai library and state that you want to use chai-http for assertions.

chai.use(chaiHttp);  

Chai has different interfaces that you can choose from. Should and expect are more readable, while you can also use the traditional assert. You can read more about the various styles here.

Pick one based on your preference. For example, expect

const expect = chai.expect;  

With this in place, it is time to write the first test.

describe('baseRoute', () => {  
    it('should respond with HTTP 200 status', () => {
        return chai.request(app)
            .get('/')
            .then(res => {
                expect(res.status).to.be.equal(200);
            });
    });
})

You have one test case here, which checks that the base route ‘/’ returns HTTP 200 status code.

To test the code, you can either transpile the test code to javascript explicitly, or do that in memory.

Typescript node is a typescript execution environment. To install it, run the following command from root directory.

npm install --save-dev ts-node  

Update the test script in package.json to

"test": "mocha --reporter spec --compilers ts:ts-node/register test/**/*.ts "

This scripts requests mocha to run the tests in the test folder and the use ts-node as the typescript environment for execution. This means that there is no need to generate the corresponding js files in ‘dist’ folder for the tests.

To run the tests, run

npm test  
> mocha --reporter spec --compilers ts:ts-node/register 'test/**/*.ts'



  baseRoute
    ✓ should respond with HTTP 200 status


  1 passing (39ms)

Congratulations, you now have successfully tested your first typescript and express app.

We will explore more detailed options like debugging, fetching data from database, generating swagger, deploying to cloud, etc. in the coming posts in this series.

Happy coding! form this post

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s