DEV Community

Cover image for Conquering the Villains: A Journey of Setting Up Node.js with Express and TypeScript
Harendra Bhujel
Harendra Bhujel

Posted on

Conquering the Villains: A Journey of Setting Up Node.js with Express and TypeScript

"TypeScript is the Robin to your Batman in the world of JavaScript programming. It's a powerful sidekick that helps you write better code with fewer errors.”

Just like a superhero gains their abilities through a unique process, setting up Node with Express and TypeScript can give you powerful tools to build robust web applications. With Node.js and Express, you can easily create web applications and APIs, and when you add TypeScript to the mix, you gain strong typing and better error checking. Ready to become a web development superhero? Let's dive in!

Battling against a supervillain
Let's start our journey by initializing a project, which is where the battle will begin. As any superhero knows, preparation is key to success. So, we'll cast the following spell to make a folder and initialize it with default settings using yarn:

mkdir express_ts_setup && cd express_ts_setup
yarn init -y
Enter fullscreen mode Exit fullscreen mode

We've successfully initialized our project and let’s add some more friends to our side. Like any good detective in a bat suit , we must be prepared for battle.

Our first challenge is the introverted Node engine. It may seem harmless, but it's a powerful force that can cause chaos if left unchecked. That's why we need to call on the help of our friends and their allies.

We'll invite express and typescript to join our superhero squad, but we must also call @types/node, and @types/express so typescript will understand our node engine and express It's like calling on your superhero friends to fight a villain, but realizing you also need their allies to win the battle. 💪

yarn add express typescript @types/node
Enter fullscreen mode Exit fullscreen mode

Now, let's create a src folder where we'll keep our files, and an index.ts file where our program will start. Like a true superhero, we need to have a strong starting point for our mission.

Folder structure of the project

With TypeScript on our side, we were ready to take on the battle. But we soon realized that TypeScript was not just any ally - he was a joker, always cracking up jokes about our code. Luckily, he was also a controller, and he helped us keep our code under control.

Despite his humorous nature, we needed TypeScript in our battle, as he was the information broker. He could tell us what was wrong with our code before we even noticed it ourselves. But there was a catch: we had to communicate with him in his own language, Fe2O3. It was a magical language, and only the detective in the bat suit could understand it.

So we armed ourselves with TypeScript, the detective's bat suit, and a good sense of humor, and set out to conquer the world of Node.js with Express and TypeScript.

// tsconfig.json
{
  "compilerOptions": {
    // Set the ECMAScript version to ES2020
    "target": "ES2020",

    // Use a custom module system called NodeNext
    "module": "NodeNext",

    // Use the nodenext module resolution strategy
    "moduleResolution": "nodenext",

    // Enable compatibility with modules that use `export =` syntax
    "esModuleInterop": true,

    // Allow importing JSON files as modules
    "resolveJsonModule": true,

    // Generate source maps for the compiled code
    "sourceMap": true,

    // Specify the directory where the compiled code will be outputted
    "outDir": "./dist",

    // Enable strict type checking rules
    "strict": true,
  },

  // Specify the files that should be included and excluded in the compilation process
     "include": ["src/**/*.ts"],
  "exclude": ["node_modules", "dist"]
}
Enter fullscreen mode Exit fullscreen mode

And so we continued on our quest, and created the index.ts file where we would start our magical process. This file would be the entry point to our application, and it would give multiple instructions to our magic.

First, we imported our friends Express and TypeScript, as well as some other helpful tools:

// we use default spell `express` which is the main spell
// and call named spell`Request` and `Response` which joker will need later
// to understand information, he's a psycho information broker after all
// ofc we will use ES module system 
import express, { Request, Response } from "express";

// instantize an app from express() function
const app = express();

// setup a simple get route 
// and return a test message

app.get("/", (req: Request, res: Response) => {
  res.json({ test: "Ok" });
});

// and finally start the server at port 5000
const PORT = 5000;
app.listen(PORT, () => {
  console.log("server has started on port");
  console.log("http://localhost:" + PORT);
});
Enter fullscreen mode Exit fullscreen mode

Excited to see our magical application come to life, we ran the node src/index.ts command in our terminal, just like we had done before with our JavaScript projects. But instead of seeing our application start up, we were met with an error message:

import express, { Request, Response } from "express";
^^^^^^

SyntaxError: Cannot use import statement outside a module
Enter fullscreen mode Exit fullscreen mode

Great! Now our friend Node understands the magic of ES modules, thanks to our configuration in package.json.

{
  "name": "expess_ts_setup",
  "version": "1.0.0",
  "main": "index.ts",
  "license": "MIT",

    // the new line we add 
    "type": "module", // "commonjs" is defualt, require() syntax
    // ******************
  "dependencies": {
    "@types/node": "^18.16.3",
    "express": "^4.18.2",
    "typescript": "^5.0.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

And let’s try again 🙂

node src/index.ts

node:internal/errors:464
    ErrorCaptureStackTrace(err);
    ^

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for C:\expess_ts_setup\src\index.ts
Enter fullscreen mode Exit fullscreen mode

Ofc it won’t work.
Our friend node engine doesn’t understand typescript. We brought @types/node so typescript could understand node

Now it looks like we need another friend to explain typescript to node

After some digging around we found out that there’s someone called ts-node which can help us do that.
so we called him yarn add ts-node -D

Now instead of calling node we call ts-node

yarn ts-node src/index.ts
Enter fullscreen mode Exit fullscreen mode

However, it seems like we are still encountering an error:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for C:\expess_ts_setup\src\index.ts
Enter fullscreen mode Exit fullscreen mode

We added some more information to our tsconfig.json file to help ts-node understand how to transpile our TypeScript code into JavaScript that node can understand. Here's the updated tsconfig.json file:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "moduleResolution": "nodenext",
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "sourceMap": true,
    "outDir": "./dist",
    "strict": true,
    "baseUrl": "./",
    "paths": {
      "@controllers": ["src/controllers/index.js"],
      "@router": ["src/router/index.js"],
      "@endPoints": ["src/router/endPoints.enum.js"],
      "@prisma": ["src/config/PrismaClient.js"]
    }
  },
  // "include": ["src/**/*"],

    // ts-node settings we added
  "ts-node": {
    "esm": true,
    "compiler": "typescript"
  }
// *****************
}
Enter fullscreen mode Exit fullscreen mode

Oh yesss!! Finally we saw what we wanted to see

server has started on port
http://localhost:5000
Enter fullscreen mode Exit fullscreen mode

Great! It's always satisfying to see things working as expected.

Now our magical tool works but we have to restart it every time we add some new features to it.

For that we all to whom to call 🙂

Our good old friend nodemon , let's call him, yarn add nodemon -D

We can now call yarn nodemon src/index.ts and our toll won’t have to restart for it to work with new features.
And lucky for us, since we already have ts-node who understands typescript , our nodemon has learned to work with ts-node automatically.

[nodemon] 2.0.22
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src\index.ts` // nodemon is starting ts-node Wow!
server has started on port
http://localhost:5000
Enter fullscreen mode Exit fullscreen mode

Phew!!
And we have finally make a magical tool that gives us power to build amazing web spell with ease. Don your developer cape and start building today!

Top comments (2)

Collapse
 
wolfvector profile image
Alejandro Torres

It did not work for me. I'm not using yarn, so I don't know if that makes a difference.

Collapse
 
gdd profile image
Towski0804

You really are my true hero!