A Step-by-Step Guide to Setting Up a Node.js and Express App with TypeScript
In this post, I will show you step by step how to setup an express rest api app with Typescript.
Requirements
Nodejs 18 or greater
Basic Javascript Knowledge
Step 1: Initialize the project
In this project we will use pnpm as our package manager. If you are not yet install in you machine, check out here (pnpm installation) how to setup in your pc/laptop.
# This command will initialize the project by create a package.json file.
pnpm init
Step 2: Install Dependencies
We will install all dependencies that will help us setup our project.
express: A fast and minimalist web application framework for Node.js.
dotenv: A zero-dependency module that loads environment variables from a .env file into process.env.
cors: A middleware that enables Cross-Origin Resource Sharing (CORS) for Express.js.
typescript: A typed superset of JavaScript that compiles to plain JavaScript.
ts-node: A TypeScript execution and REPL for Node.js. It provides an interactive TypeScript console and also allows running TypeScript files directly.
tsconfig-paths: A module that adds support for TypeScript path mapping when executing TypeScript files.
nodemon: A utility that monitors for changes in files and automatically restarts the Node.js application when changes are detected.
@types/express: TypeScript definitions for the Express.js framework.
@types/node: TypeScript definitions for Node.js.
Step 3: Configuring TypeScript Compiler Options
tsc --init
When you run the command above, TypeScript will generate a basic tsconfig.json file with default settings. The tsconfig.json file is used to configure various aspects of the TypeScript compiler's behavior for your project.
The tsconfig.json options used in this example
tsconfig.json
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
"rootDir": "./src", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
"baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */
/* Emit */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
/* Interop Constraints */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
/* Completeness */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
Step 4: Create Server and App file
Create a folder src then add two file files - server.ts and app.ts
servers.ts
import "dotenv/config";
import createServer from "server";
const startServer = () => {
const app = createServer();
const port: number = parseInt(<string>process.env.PORT, 10) || 4000;
app.listen(port, () => {
console.log(`[server]: ⚡⚡Server is running at port ${port}`);
});
};
startServer();
app.ts
import express, { Application, Request, Response, NextFunction } from "express";
In this example, we are going to add product as an business module. First create product folder with the following files: routes.ts , controller.ts and model.ts .
Here is an explanation of the different components of the test script:
"NODE_ENV=test": This sets the NODE_ENV environment variable to 'test'. The NODE_ENV variable is commonly used to indicate the environment in which the application is running. In this case, it's set to 'test', suggesting that the application is running in a testing environment. This can be useful for configuring the application differently based on the environment.
mocha: Mocha is a feature-rich testing framework for JavaScript and Node.js applications. It provides a flexible and powerful API for writing tests and generating detailed test reports.
-check-leaks: This option tells Mocha to check for global variable leaks. It helps ensure that tests are properly isolated and that one test doesn't inadvertently affect another.
-r ts-node/register: This option registers the ts-node module with Mocha. ts-node allows Mocha to directly run TypeScript files without the need for compilation.
-r tsconfig-paths/register: This option registers the tsconfig-paths module with Mocha. tsconfig-paths helps handle TypeScript path mapping in tests, ensuring that TypeScript can resolve module paths correctly.
"src/test/**/*.spec.ts": This is the glob pattern that specifies the location of the test files. In this case, it looks for all files with the .spec.ts extension in the src/test directory and its sub-directories.
When you run the test script, Mocha will discover and execute all the test files matching the specified pattern. It will report the test results, including any failures or errors encountered during the tests.
Start write unit test
Inside src file create another folder test then based on your business modules create test file.
for example, inside test folder create auth/index.spec.ts
auth/index.spec.ts
test/auth/index.spec.ts
import request from "supertest";
import { expect } from "chai";
import createServer from "server";
const app = createServer();
describe("auth routes", function () {
it("/auth responds with 200", function (done) {
request(app).get("/auth").expect(200, done);
});
});
The test code above uses mochasupertest and chai to test authentication routes . It verifies that a GET request to "/auth" results in a 200 status code response.