Node.js (Express) with TypeScript, Eslint, Jest, Prettier and Husky - Part 1
Tags: typescript, express, eslint, jest
Published: 2020-05-31 21:55:45

I feel ❤ that everyone (waiting for reactions 😎) is using Typescript nowadays. So I thought I wanted to share with you how we setup our Node.js applications here at [Ornio AS](https://ornio.no).

In this part we will be covering:
- Project initialization
- Setup Typescript
- Setup Express.js
- Setup Nodemon

Are you in the hurry, scroll down to the source code :)

> Btw did I tell you this is my first post here @dev.to so share some love 👊.

# Initialize the project

Create `package.json` by opening your terminal, create a folder (name it as you wish) and type:
```
npm init
```

Answer the questions prompt by terminal and confirm creation of the package.json file at the end.

Here is my package.json file:
```json
{
  "name": "nodejs-express-typescript-howto",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ornio-no/post-nodejs-express-typescript-howto.git"
  },
  "keywords": [
    "Nodejs",
    "typescript",
    "express"
  ],
  "author": "Flamur Mavraj (Ornio AS)",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/ornio-no/post-nodejs-express-typescript-howto/issues"
  },
  "homepage": "https://github.com/ornio-no/post-nodejs-express-typescript-howto#readme"
}
```

# Install and configure Typescript

```
npm i -D typescript ts-node
```

`typescript` will install Typescript package.
`ts-node` will install Typescript node runner so we don't need to build the application everytime we do a change, will be used with Nodemon.

After the installation run following command:
```
npx typescript --init
```

This will create `tsconfig.json` file with default options enabled and comments describing each options.

So here is my file after some clean up:
```json
{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "sourceMap": true,
        "outDir": "./build",
        "rootDir": "./src",
        /* Strict Type-Checking Options */
        "strict": true,
        "noImplicitAny": true,
        /* Module Resolution Options */
        "moduleResolution": "node",
        "baseUrl": "./src",
        "esModuleInterop": true,
        /* Advanced Options */
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
    },
    "lib": ["es2015"],
    "include": ["src/**/*"],
    "exclude": ["node_modules"]
}

```

I'm not going to describe each of the options above but following two options are important:

`outDir` Its the directory where we want to compile our source code to, others may call it `dist` as well.
`rootDir` Its the directory where our Typescript files are going to be located.

Next step is to setup scripts in package.json:
```json
{
    // ...
    "scripts": {
        "start": "nodemon",
        "build": "tsc",
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    // ...
}
```

`start` will start nodemon, will configure that later, at the end.
`build` will compile our code using Typescript based on our `tsconfig.json`-file.

# Setup Express and start the server

Install needed packages:
```
npm i -S express
npm i -D @types/express
```

Since Express does not have build in Typescript definitions we need the second package.

Then create `src/index.ts` with following content:

```typescript
import express, { Application, Request, Response, NextFunction } from 'express';

// Boot express
const app: Application = express();
const port = 5000;

// Application routing
app.use('/', (req: Request, res: Response, next: NextFunction ) => {
    res.status(200).send({data: 'Hello from Ornio AS'});
});

// Start server
app.listen(port, () => console.log(`Server is listening on port ${port}!`));
```

Let's stop for a minute so I can explain what's happening in the code above.

On our first line we import express and its definitions (remember @types/express). After that we initiate express and defines the port (to be used at the end). And before starting the server we add a simple route and its function with argument definitions. 

So why do we need these definitions?
This is the power of Typescript, these definitions are signature of the functions/arguments and will tell us how to use them. Yes you can create your own definitions but I'm not going to explain that here. These definitions will help you writing better code!

### Compile/build and run the application

To run your application first we need to build it and then run it. 
```
npm run build
```

Then run it using node:
```
node build/index.js
```

In your console you should see: `Server is listening on port 5000!`.

You can test the server by using `curl`:
```
curl localhost:5000
```

It should return `{"data":"Hello from Ornio AS"}`.

Almost done, let's wrap it up with setting nodemon.

# Setup Nodemon for development

While developing the application we need a better way of handling file changes without building and restarting the server each time, for this we are going to use nodemon.

Installing nodemon:
```
npm i -D nodemon
```

And then configure it by creating a new file named `nodemon.json`:
```json
{
    "watch": ["src"],
    "ext": ".ts",
    "ignore": [],
    "exec": "ts-node ./src/index.ts"
}
```

This will let nodemon watch `src` folder, by watching .ts files and execute/re-run `ts-node ./src/index.ts` when these files change.

Lets run the server and go ahead change something in `./src/index.ts` and you will see nodemon will detect the changes and restart the server:
```
npm run start
```

Where did `start` command come from? While configuring Typescript :)

# Source code
You can find the source code [here](https://github.com/ornio-no/post-nodejs-express-typescript-howto/tree/part-1).

# Need help?
Comment here or ping me on Twitter and I will gladly try to help you :)

___

# Whats next?
- Setup Eslint, Prettier and Husky (Part 2)
- Testing using Jest and Supertest (Part 3)