Introduction
Today I’m going to show you guys How to set up a full-stack project with React JS, Express JS, and Typescript. The advantage of using Typescript over Javascript is it gives robustness to your applications and enabling the latest ECMAScripts features to use with the most powerful feature which is optional static type-checking.
Prerequisites :
To complete this tutorial, yo will need :
- A local Development environment of Node JS. Follow How to install Node JS and Create a Local Development.
- Access to the package manager: npm or yarn. Follow NPM vs Yarn for more information about npm(Node Package Manager) and Yarn.
- Basic knowledge of Node JS and Express JS. Follow How to Create the Server in Express JS.
- Basic knowledge of Typescript.
- Basic knowledge of React.
Create a server in Express and Typescript
Start by creating a new directory where you want to keep all files of the projects. Open the terminal on folder location and run the below command for creating package.json
file.
mkdir react-express-typescript-starter
cd react-express-typescript-starter
npm init -y
After created package.json
file, we will create one folder in root location of project folder and give the name server
.
mkdir server && cd server
Dependencies Installation:
For creating the express server compatible for running on typescript, we need to install the packages and related @types package (if you will install express then you also need to install @types/express). @types modules containing the type definition of the main package. For example, if you will install express and @types/express then @types/express contains all static definitions of express package.
Note: we need to install all @types modules as dev dependencies.
Run the below command for installing all packages and its @types
yarn add body-parser cors dotenv express find-config morgan
yarn add -D @types/body-parser @types/cors @types/dotenv @types/express @types/find-config @types/morgan
if you need to use npm, please use below commands:
npm install --save body-parser cors dotenv express find-config morgan
npm install --save-dev @types/body-parser @types/cors @types/dotenv @types/express @types/find-config @types/morgan
Folder Hierarchy of Server
Refer the folder structure in below image for better understanding:
index.ts :
import express, {Application, Router} from "express";
class App {
app: Application;
router: Router;
constructor() {
this.app = express();
this.router = Router();
this.initRoute(this.app);
}
initRoute(app:Application) {
app.get('/', (req, res) => res.send('Express JS server in Typescript'));
}
}
export default new App().app;
In the above code of snippet, we create App
class which having two member variable app
and router
. Before that, we will import the express, Application and Router
from an express module. At the end of the line, we export an instance of App class.
./bin/www.ts:
This file having the code related to server implementation like how to fetch environment variables
, set the port in server configuration, and listening to the server on a specific port.
#!/usr/bin/env node
import http from 'http';
import * as dotenv from 'dotenv';
import chalk from 'chalk';
import App from '../index';
import findConfig from 'find-config';
dotenv.config({path: findConfig('.env') ?? ""});
const normalizePort = (val:any) => {
const port = parseInt(val, 10);
if (isNaN(port)) {
return val;
}
if (port >= 0) {
return port;
}
return false;
};
const onError = (error:any) => {
if (error.syscall !== 'listen') {
throw error;
}
let bind = typeof port === 'string'
? `Pipe ${ port}`
: `Port ${ port}`;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(`${bind } requires elevated privileges`);
process.exit(1);
break;
case 'EADDRINUSE':
console.error(`${bind } is already in use`);
process.exit(1);
break;
default:
throw error;
}
};
const onListening = () => {
console.log(chalk.yellow('=========================================='));
console.log(chalk.green(`Server listening on ${port}`));
console.log(chalk.yellow('=========================================='));
const addr:any = server.address();
const bind = typeof addr === 'string'
? `pipe ${ addr}`
: `port ${ addr.port}`;
};
const port = normalizePort(process.env.PORT);
App.set('port', port);
const server = http.createServer(App);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
In the above code of snippet, we will fetch the environment variables from .env
file and will create the server with the help of http
node js module and set the port by the use of App.set()
method. If we will face some error on bootup of the server then onError
method otherwise onListening
method will call.
./config/config.ts:
module.exports = {
port: process.env.PORT
}
In the above code of snippet, we will create an object which has all values from .env
file and then export this object as module.exports
.
Add .env file:
PORT=9000
We will create .env
file in the root of the project and don’t push this file into git. We will add PORT=9000
in .env
file. When we will start the server, server will take port number from .env file.
Setup tsconfig.json file:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"rootDir": "./",
"outDir": "./build",
"esModuleInterop": true,
"strict": true
},
"include": ["server/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
Next, we will create a tsconfig.json
file in the root directory. This file has all the information about the compilation of typescript code into javascript code. In tsconfig.json
file, you are free to customize the configuration of compilation and typescripts.
compilerOptions
is a mandatory field in this file that having some sub-values.target
is giving information about which version of ECMAScript is using for the compilation.module
is giving information about the module which we will use for compilation.rootDir
is the source of typescript code.outDir
is the destination folder where all complied files will store.- With flag
esModuleInterop
we can import Common JS modules in compliance with es6 specs. strict
is using for strict checks.include
is using for which files and folders will include in the compilation process.exclude
is using for which files and folders will exclude in the compilation process.
Modify package.json:
"scripts": {
"delete": "del-cli --force ./build",
"build": "tsc",
"server": "cd build && export NODE_ENV=devlopment && node server/bin/www.js",
"prestart": "concurrently \"yarn run delete\" \"yarn run build\"",
"start": "yarn run server"
},
For running the express js server with typescript, we need to modify the package.json
file. We will add some scripts
commands. Before modifying, we need to install some packages:
yarn add concurrently del-cli ts-node tslint typescript
npm install --save concurrently del-cli ts-node tslint typescript
delete
is using to delete thebuild
folder.build
is using to compile the typescript code into javascript.server
is using for setting theNODE_ENV
and thewww.js
file.prestart
is using to a run some comands before starting the server.start
is using for run the server.
Run the server
For running the server, please run the below command in the terminal at project directory location.
yarn run start
npm run start
Hit the url http://localhost:9000/
in browser for checking server is running or not.
Conclusion:
At the end of this tutorial, you created the server with express js
and typescript
. With the use of Typescript, we will use lots of typescript’s benefits and it’s all depends on your requirement for development of the project.