How to set up an Express.js project with TypeScript
Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. Honestly, I haven't been using it for quite some time, but now I want to update my old experience with Express.js and a TypeScript setup. Besides, Express.js version 5 (beta) is now available and maybe in future articles, I'll share my thoughts and experience about it. But today, we're going to create a setup with TypeScript and Express.js with an easy-to-use folder structure. And the first thing we need is to generate an Express.js project.
Generate Express.js project
As a first step, we need to have Node.js itself installed on the machine. Open a terminal and type 'node -V' and if it shows you a version, you're good to go. For those who see an error, please follow the link , download the Node.js LTS version, and install it by following the instructions on the site.
Next, create a folder where you want to have your project. You can name it whatever you want. For the example let's name it 'server'.
Open your terminal and past the commands below and run them one after another:
# Navigate to the folder you're going to have you project in
cd ~/path/to/any/folder/you/re/going/to/have/your/project/in
# Generate in that folder a new folder with name 'server'
mkdir server
# Initialize a package.json file with default values
npm init --yes
After executing these 3 commands, you'll have a package.json file which is going to look like this:
{
"name": "work",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
And now, let's add Express.js to the project by running the command:
npm install express
It will generate a package-lock.json file and a node_modules folder in the server folder. And also, in the package.json file, a new block "dependencies" with express.js will appear.
Create a Hello World server app with Express.js
Creating a simple server with Express.js is a 3 steps deal:
Take a look at the picture, can you identify each step on your own?
Let's start from the start. Go to the 'server' folder and create a new file index.js which is going to be the entry point (the file node.js is going to run first) where we are going to put our server's configuration.
1. Now, let's import express.js from the modules
const express = require("express");
const app = express();
2. Define one route which is going to respond to a GET request to the https://localhost:8080/ URL with the text "Hello world!" as a response.
app.get("/", (req, res) => {
res.send("Hello world!");
});
3. Turn on express.js to listen to port 8080
app.listen(8080, () => {
console.log(`server started at https://localhost:${8080}`);
});
And that's it. Our Node.js server with Express.js is ready. But how can we run it? That's where we would ask Node.js to help us. Open your terminal and run the command
node index.js
This command will tell Node.js to run our index.js file with the Express.js server and when it's done, you should the console.log we declared in step 3
And if you would open your browser at https://localhost:8080 you'll see the text "Hello world!" we declared in step 2.
But wait a minute, should we run this 'node index.js' command from the terminal each time? Of course not. Besides, this command is gonna be much longer with TypeScript support, so let's place it in the package.json file:
The dot instead of index.js as before is just a shortcut for an index file in the folder. So now, we just need to run npm run start and everything is going to work as before.
As we have our express.js up and running, let's add TypeScript support, because we're great developers and want to have types to protect ourselves from ourselves :)
If you're going to make changes, to this setup, you would need to restart your server manually via the terminal. At the end of the article, I'll put a Bonus section on how to fix that.
领英推荐
Add TypeScript Support
Since we're in the world of Node.js, I mean, in the Node.js environment, and it only understands the JavaScript language, the TypeScript code needs to be transpiled to JavaScript before the app is used in runtime. And for that we're going to use ts-node which transforms TypeScript into JavaScript, enabling you to directly execute TypeScript on Node.js without precompiling.
The first step we need to install the typescript and ts-node packages, but since it's only the development-related packages we would add an additional -D flag which indicates that the packages are going to be installed for development mode and will be deleted on production.
npm install typescript ts-node -D
Each time I install packages I'd like to verify it was added successfully to the package.json file. This time, packages should be added to the "devDependencies" section
Now, we need to configure the TypeScript. To do that, we need to create a 'tsconfig.json' file in the 'server' folder and put the following config there:
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"rootDir": "./",
"esModuleInterop": true
}
}
It's just a basic config, and the information about all properties you can find in the official TypeScript documentation .
Now, we can change the extension of the main file from index.js to index.ts.
Open the package.json file and update the "main" property as well from js to ts.
And the last step is to update our "start" script. Instead of "node" we're going to use "ts-node" now. As simple as that.
Now we can run our server with the same "npm run start" command and open the https://localhost:8080 and we'll see the text "Hello world!" as before. But what now?
Now we can use types. For the express.js project, we only need to add support for node.js and express.js types. We can install it as a dev dependency with the command:
npm install @types/node @types/express -D
(Don't forget to verify that they were added successfully to the package.json "devDependencies" section)
Now, we can use types with the latest ES6 features like imports. Let's update our index.js code with a TypeScript version
import express, { Request, Response } from 'express'
const app = express();
app.get("/", (req: Request, res: Response) => {
res.send( "Hello world!" );
});
app.listen(8080, () => {
console.log(`server started at https://localhost:${8080}`);
});;
As you see, now, since we have specific types of requests and responses that come from the 'express' module (actually from the @types/express) we can be sure of what types we're using across our server application. And also we can now see all things our variables support all thanks to TypeScript
Bonus
As I promised, the bonus part is going to be about watching mode. Developing apps without hot-reloading is a sin in the IT world (and I saw a lot of examples of projects even with senior developers on them). You should not waste your time in such a way. Besides, it's not that hard to fix it. All you need is to use a nodemon package.
Since we only need it in development mode let's put -D flag when installing
npm install nodemon -D
When it's done, add a new serve command to the package.json file
"serve": "nodemon index.ts"
At the end the "package.json" should look like this:
And now, you can run the server with hot-reloading
npm run serve
As you see, it's watching for extensions .ts and .json. That means if any files in the server folder with that extension would be updated the nodemon will automatically rebuild them and so you can now focus on the development process and don't be distracted by restarting the server after changing a file.
Congratulations, you made it. This one was a bit longer than I expected. Thanks for spending your time with me and if you'll have any questions or you are stuck following the tutorial, please, let me know, I'll be glad to help you.
Cheers.