Node.Js Cheatsheet



Node.Js is an open-source, cross-platformJavaScriptruntime environment. It allows developers to executeJavaScriptcode outside the web browsernode.Jsenables developers to build server-side applications using the same language they used to develop front-end applications. Full-stack developers need this tool because it lets them make both the front-end UI (user interface) and the back-end logic in the same language, which speeds up the development process.

Table of Content

  1. Introduction to Node.Js
  2. Node.Js Installation & SetUp
  3. Node.Js Fundamental
  4. Node.Js Core Module
  5. Working with NPM (Node-Package-Manager)
  6. Creating a Simple HTTP Server
  7. Express.Js Framework
  8. Working with Databases
  9. Asynchronous JavaScript in Node.Js
  10. File System Operation
  11. Working with Apis
  12. Authentication & Security
  13. Error Handling & Debugging
  14. Websocket & Real-time Application
  15. Deploying a Node.Js Application
  16. Best Practise & Performance Optimization

1. Introduction to Node.Js

What is Node.Js?

Node.Js is a JavaScript runtime environment that allows us to run JavaScript on the server side. It is an open-source cross-platform and widely used by large businesses.

It's run on a single thread, using an event loop to handle multiple requests simultaneously. It uses the V8 JavaScript engine for Google Chrome.

Features & Benefits

Following is the list of features −

  • Asynchronous & Event Drive: Node.Js operates on event-drivenarchitecture, using a non-blocking I/O model. This allows it to handle multiple requests concurrently.
  • Single Threaded: Node.Js uses a single single-threaded event loop to handle requests. This simplifies development, and debugging, reducing concerns about concurrency issues.
  • Scalable: Due to non-blocking architecture, Node.js can handle a large number of concurrent connection with minimal resources.
  • Microservices: Node.Js is suitable for microservices architecture, where applications are built as a collection of loosely coupled services that can be developed and deployed independently.

Following is the list of benefits −

  • High Performance: Node.Js offers high performance for real-time applications due to its event-driven and non-blocking architecture.
  • Improved Response Time: Node.Js can improve application response time and boost performance, especially for I/O-bound operations.
  • Real-Time Application: Node.Js can build real-time applications like chat applications and gaming platforms due to its ability to handle concurrent requests efficiently.
  • Easy to Learn & Use: Node.Js uses JavaScript, which is a widely used language, making it easy for developers to learn and adapt.
  • Coast-Effective: Using node.js for front-end and back-end development can reduce development cost and simplify team structure.

2. Node.Js Installation & SetUp

Installing Node.Js & npm

Installing Node.Js on Windows is very simple visit the Node.Js official website. Then run the installer and follow the instructions.

  • Go to node website
  • Click the "LTS" version to download the windows installer −
  • Run the downloaded .msi file −
  • Accept the default setting −
  • Restart your computer −

Checking Node & npm versions

To verify the installation of Node, open command prompt CMD and type node -v.

3. Node.Js Fundamental

Global Objects (__dirname, __filename, process, etc.)

The objects that are available throughout the process or application are called global objects. Global objects are accessible from anywhere in the program without requiring an explicit import.

__dirname: This global object holds the absolute directory path of the current JavaScript file. That is important for server-side code like logging, finding metadata, etc.

console.log("Directory Name:", __dirname);

__filename: This global object holds the absolute file path of the current JavaScript file.

console.log("File Name:", __filename);

process: This global object gives details about the running Node.Js process, such as environment variables, memory usage, and arguments.

// get nodejs environment
console.log("Environment:", process.env.NODE_ENV);

CommonJS vs Es Modules (require vs import)

In Node.Js, we use a module system to manage and import/export code between different files. There are two module systems −

CommonJS (CJS) − The traditional module system

It is a default module system in Node.Js that uses require() and module.export to import and export modules respectively, and runs synchronously (not ideal for top-level await).

Example: Demonstrating CommonJS

Exporting in CommonJs (math.js)

// math.js
function add(a, b) {
   return a + b;
}

function subtract(a, b) {
   return a - b;
}
// Export functions
module.exports = { add, subtract };

Importing in CommonJS (app.js)

// app.js
const math = require('./math');
console.log(math.add(5, 3));
console.log(math.subtract(9, 4));

ES Module (ESM) − The modern JavaScript module system

It introduced in ES6 (ECMAScript 2015) uses import and export. It supports asynchronous loading (work with top-level await).

Example: Demonstrating Es Module

Exporting in ESM (math.mjs)

// math.mjs
export function add(a, b) {
   return a + b;
}

export function subtract(a, b) {
   return a - b;
}

Importing in ESM (app.mjs)

// app.mjs
import { add, subtract } from './math.mjs';
console.log(add(5, 3));
console.log(subtract(9, 4));

Event Loop & Asynchronous Programming

Although Node.Js is single-threaded, its asynchronous programming can handle multiple tasks strongly. This is possible due to the Event Loop, which allows Node.js to perform non-blocking I/O operations.

Event Loop: The event loop is the core mechanism in Node.Js that, enables asynchronous, non-blocking operations by handling multiple tasks easily.

The event-loop is needed because JavaScript runs single-threaded, meaning it executes one task at a time. Therefore, event-loop allows Node.Js to handle multiple operations like file reading, API calls, or database queries without waiting for each task to be completed before moving to the next.

Asynchronous Programming: Asynchronous programming is a programming paradigm that allows tasks to be executed without waiting for previous tasks to be completed.

Example: Synchronous vs Asynchronous Execution

Synchronous Code (Blocking)

console.log("Start");
function syncTask() {
   // Simulating a long-running task
   for (let i = 0; i < 1e9; i++) {}
   console.log("Sync Task Done");
}
syncTask();
console.log("End");

Output

Start
Sync Task Done
End

Asynchronous Example (Non-blocking)

console.log("Start");
setTimeout(() => {
   console.log("Timeout Done");
}, 2000);

console.log("End");

Output

Start
End
Timeout Done

4. Node.Js Core Module

Node.Js has several built-in core modules that provide essential functionality without requiring installation. These modules help the developer interact with the file system, network, operating system, and more.

File System (fs) Module

The fs module allows us to manipulate the file by reading, writing, deleting, and managing files.

Example: Reading a File (fs.readFile)

const fs = require('fs');

fs.readFile('example.txt', 'utf8', (err, data) => {
   if (err) throw err;
   console.log("File Content:", data);
});

Example: Writing to a File (fs.writeFile)

fs.writeFile('example.txt', 'Hello, tutorialspoint!', (err) => {
   if (err) throw err;
   console.log("File written successfully!");
});

Path Module (path)

The path module helps in working with file path easily.

Example: Getting File Name and Directory

const path = require('path');
console.log("File Name:", path.basename(__filename));
console.log("Directory Name:", path.dirname(__filename));
console.log("File Extension:", path.extname(__filename));

Example: Joining Paths

The path.join() ensures proper path formatting across Os platforms.

const fullPath = path.join(__dirname, 'files', 'data.txt');
console.log("Full Path:", fullPath);

HTTP Module (http)

The http module is used to create a web server in Node.Js.

Example: Creating a Simple HTTP Server

Handles incoming request and sends responses. Listen on port '3000' to start the server.

const http = require('http');

const server = http.createServer((req, res) => {
   res.writeHead(200, { 'Content-Type': 'text/plain' });
   res.end('Hello, World!');
});

server.listen(3000, () => {
   console.log("Server running on http://localhost:3000");
});

OS Module (os)

The os module provides the system informations like CPU, memory, and platform details.

Example: Getting System Info

OS module is useful for monitoring system performance.

const os = require('os');

console.log("OS Platform:", os.platform());
console.log("OS Architecture:", os.arch());
console.log("Total Memory:", os.totalmem() / 1024 / 1024, "MB"); 
console.log("Free Memory:", os.freemem() / 1024 / 1024, "MB"); 
console.log("CPU Cores:", os.cpus().length);

Event Module (events)

The event module allows handling custom event in Node.Js.

Example: Creating & Emitting an Event

Here, the on() method register an event listener, emit() trigger the event.

const EventEmitter = require('events');
const emitter = new EventEmitter();

emitter.on('greet', (name) => {
   console.log(`Hello, ${name}!`);
});
emitter.emit('greet', 'Alice');

5. Working with NPM (Node-Package-Manager)

In Node.Js, we use npm (node package manager) to install and manage dependencies (library/modules). There are two main types of package installation.

Local Installation

It installs the package or module inside the project directory (node_modules). The installed package will be only available for that project.

npm install lodash/npm i lodash

After the installation, it creates a node_modules folder and updates package.json.

Global Installation

It installs the package system-wide, making it available globally for all projects. This is useful for CLI tools like nodemon and TypeScript.

npm install -g nodemon

Now, nodemon is available for any project without installing it locally.

package.json & package-lock.json

package.json: It stores project metadata like name, version, description, and dependencies. The package.json is automatically created when running.

npm init

package-lock.json: It locks the exact version of installed dependencies. Ensure consistency across different environments. package-lock.json is automatically created when installing packages.

package-lock.json

{
  "name": "my-app",
  "dependencies": {
    "express": {
      "version": "4.17.3",
      "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz"
    }
  }
}

6. Creating a Simple HTTP Server

Creating a simple HTTP server in Node.js is an ideal way to start web development. Lets break it down into steps.

Using The http Module

The HTTP module in node.js allows us to create a web server that listens for requests and sends responses.

Example: Basic HTTP Server

const http = require('http');
// Create a server
const server = http.createServer((req, res) => {
   res.writeHead(200, { 'Content-Type': 'text/plain' });
   res.end('Hello, tutorialspoint!');
});

// Start the server on port 3000
server.listen(3000, '127.0.0.1', () => {
   console.log('Server running at http://localhost:3000/');
});

Handling Request and Response

Handling Request: We can handle different types of request by checking the req.method and req.url property.

const http = require('http');
const server = http.createServer((req, res) => {
   if (req.method === 'GET' && req.url === '/') {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('Welcome to the homepage!\n');
   } else if (req.method === 'GET' && req.url === '/about') {
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('About us page\n');
   } else {
      res.writeHead(404, {'Content-Type': 'text/plain'});
      res.end('Page not found\n');
   }
});

server.listen(3000, '127.0.0.1', () => {
   console.log('Server running at http://127.0.0.1:3000/');
});

Handling Response: We can send different types of content in content in the response, like JSON, HTML, etc.

const http = require('http');

const server = http.createServer((req, res) => {
   res.writeHead(200, {'Content-Type': 'application/json'});
   res.end(JSON.stringify({ message: 'Hello tutorialspoint, JSON!' }));
});

server.listen(3000, '127.0.0.1', () => {
   console.log('Server running at http://127.0.0.1:3000/');
});

7. Express.Js Framework

Express.Js is an open-source web application framework for building the back end of mobile and web apps. It's written in JavaScript and runs within the Node.js runtime environment.

Setting up Express

To set up Express.Js, run the following command in your project directory. This installs Express.Js and adds it to package.json.

npm install express

Creating Routes & Middleware

Routes in Express.js specify how an application sends client requests to certain endpoints, which are identified by a URL (path) and an HTTP method. Each route is connected with an HTTP method, and each path has a handler function.

Middleware in Express.js is a function that handles requests and responses as they pass through the application. It can perform tasks like authentication logging and error handling.

Example: Creating Routes in Express.Js

app.get('/', (req, res) => {
   res.send('Home Page');
});

app.get('/about', (req, res) => {
   res.send('About Page');
});

app.post('/submit', (req, res) => {
   res.send('POST Request Received');
});

app.put('/update', (req, res) => {
   res.send('PUT Request Received');
});

app.delete('/delete', (req, res) => {
   res.send('DELETE Request Received');
});

Example: Using a Simple Middleware

const logger = (req, res, next) => {
   console.log(`${req.method} ${req.url}`);
   next(); // Move to the next middleware or route
};

app.use(logger);

app.get('/', (req, res) => {
   res.send('Middleware Example');
});

Handling Requests & Responses

Handling request and response objects in Express.JS is fundamental for handling HTTP interactions between a client and the server.

Example: Accessing Request Data (req Object)

app.get('/user/:id', (req, res) => {
   // Extracting route parameter
   const userId = req.params.id;
   res.send(`User ID: ${userId}`);
});

Using body-parser & cors

In Express.Js, body-parser is a middleware function that parses the data sent in the HTTP request.

npm install body-parser

Setup body-parser middleware

const bodyParser = require('body-parser');
// Parses JSON data
app.use(bodyParser.json());
// Parses form data
app.use(bodyParser.urlencoded({ extended: true }));

The CORS (Cross-Origin Resource Sharing) is another middleware that limits which domains can make requests to your server, ensuring secure communication between different origins.

npm install cors

Setup cors Middleware

const cors = require('cors');
// Enables CORS for all routes
app.use(cors());

8. Working with Databases

Using JavaScript code with Node.Js runtime environment to interact with the database system, allowing us to do operations like storing, retrieving, updating, and deleting data from the database.

Connecting Node.js with MySQL

To connect the Node.Js with MySQL. First, we need to install MySQL Package Using the following command.

npm install mysql

Setup MySQL Connection

const mysql = require('mysql');

// Create a connection
const db = mysql.createConnection({
   host: 'localhost',
   user: 'root',
   password: '',
   database: 'testdb'
});

// Connect to MySQL
db.connect((err) => {
   if (err) throw err;
   console.log('Connected to MySQL');
});

Connecting Node.js with MongoDB

To connect the Node.Js with mongoDB. First, we need to install MongoDB Package Using the following command.

npm install mongodb

Setup MongoDB Connection

const { MongoClient } = require('mongodb');

const url = "mongodb:
const client = new MongoClient(url);

async function connectDB() {
   try {
      await client.connect();
      console.log("Connected to MongoDB");
   } catch (err) {
      console.error(err);
   }
}
connectDB();

CRUD Operations (Create, Read, Update, Delete)

Perform CRUD operations with MySQL

// Create a table
const createTable = `CREATE TABLE users (
   id INT AUTO_INCREMENT PRIMARY KEY,
   name VARCHAR(255),
   email VARCHAR(255)
)`;

db.query(createTable, (err, result) => {
   if (err) throw err;
   console.log('Users table created');
});

// Insert Data (Create)
const user = { name: "Aman", email: "aman@example.com" };
db.query('INSERT INTO users SET ?', user, (err, result) => {
   if (err) throw err;
   console.log('User added:', result.insertId);
});

// Fetch Data (READ)
db.query('SELECT * FROM users', (err, results) => {
   if (err) throw err;
   console.log('Users:', results);
});

//Update Data (Update)
db.query('UPDATE users SET name = ? WHERE id = ?', ["Alice Smith", 1], (err, result) => {
   if (err) throw err;
   console.log('User updated:', result.affectedRows);
});

// Delete Data (DELETE)
db.query('DELETE FROM users WHERE id = ?', [1], (err, result) => {
   if (err) throw err;
   console.log('User deleted:', result.affectedRows);
});

Perform CRUD Operation With MongoDB

// Insert Data (Create)
async function insertUser() {
   const db = client.db('testdb');
   const users = db.collection('users');
   
   const result = await users.insertOne({ name: "Alice", email: "alice@example.com" });
   console.log("User inserted:", result.insertedId);
}

insertUser();

// Fetch Data (Read)
async function getUsers() {
   const db = client.db('testdb');
   const users = db.collection('users');
   
   const data = await users.find().toArray();
   console.log("Users:", data);
}

getUsers();

// Update Data (UPDATE)
async function updateUser() {
   const db = client.db('testdb');
   const users = db.collection('users')
   
   const result = await users.updateOne(
      { name: "Alice" },
      { $set: { name: "Alice Smith" } }
   );
   console.log("User updated:", result.modifiedCount);
}

updateUser();

// delete Data (DELETE)
async function deleteUser() {
   const db = client.db('testdb');
   const users = db.collection('users');
   
   const result = await users.deleteOne({ name: "Alice Smith" });
   console.log("User deleted:", result.deletedCount);
}
deleteUser();

9. Asynchronous JavaScript in Node.Js

Asynchronous JavaScript is a key concept of the Node.Js, allowing non-blocking operations for improved performance. There are three main ways to handle Asynchronous code −

  • Callbacks: A function is passed as an argument of another function and executed latter. It can lead to "callback hell" when nested.
  • Promises: An object representing future value (either resolved or rejected) It avoid uses callback hell.
  • Async/Await: Async and wait make promises easier to write. Async makes the function return a promise. Await makes function wait for a promise.

Example: Callbacks

const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
   if (err) {
      console.error('Error reading file:', err);
      return;
   }
   console.log('File content:', data);
});

Example: Promises

const fs = require('fs').promises;
fs.readFile('file.txt', 'utf8')
.then(data => console.log('File content:', data))
.catch(err => console.error('Error reading file:', err));

Example: Async/Await

const fs = require('fs').promises;
async function readFileAsync() {
   try {
      const data = await fs.readFile('file.txt', 'utf8');
      console.log('File content:', data);
   } catch (err) {
      console.error('Error reading file:', err);
   }
}
readFileAsync();

Handling Error

We can handle the error in the Async code. Following are the steps to handle errors −

  • Try-Catch Blocks: For synchronous code
  • Error Handling in Callbacks: For asynchronous code
  • Promise .catch(): For promises
  • Promise .catch(): For promises
  • Async/Await with Try-Cath: For async/await functions

Example: Handling Errors in Async Callbacks

In asynchronous operations that use callbacks, the first parameter is usually an error object.

const fs = require('fs');
fs.readFile('nonexistent.txt', 'utf8', (err, data) => {
   if (err) {
      console.error("File read error:", err.message);
      return;
   }
   console.log(data);
});

10. File System Operation

Node.Js provides us with an 'fs' (File System) module to work with files and directories. It allows us to read, write, update, delete, and manipulate the files asynchronously or synchronously.

Reading/Writing Files

Reading a file means fetching its content to use within the application. Writing a file means creating a new file or overwriting an existing file with new content.

Example: Asynchronous & Synchronous File Reading

const fs = require('fs');

// Reading file Asynchronously
fs.readFile('example.txt', 'utf8', (err, data) => {
   if (err) {
      console.error("Error reading file:", err.message);
      return;
   }
   console.log("File Content:", data);
});


// Reading file Synchronously
try {
   const data = fs.readFileSync('example.txt', 'utf8');
   console.log("File Content:", data);
} catch (err) {
   console.error("Error:", err.message);
}

Example: Asynchronous & Synchronous File Writing

const fs = require('fs');

// Writing file Asynchronously
fs.writeFile('example.txt', 'Hello, Node.js!', (err) => {
   if (err) throw err;
   console.log('File written successfully!');
});

// Writing file Synchronously
try {
   fs.writeFileSync('example.txt', 'Hello, Synchronous Node.js!');
   console.log('File written successfully!');
} catch (err) {
   console.error("Error:", err.message);
}

Creating/Deleting Files

If a file does not exist, it will be created using fs.writeFiles() or fs.open(). Where removing a file permanently from the system is known as deleting a file.

Example: Creating A File

const fs = require('fs');
// Creating a file
fs.open('newfile.txt', 'w', (err, file) => {
   if (err) throw err;
   console.log('File created!');
});

Example: Deleting A File

const fs = require('fs');
// Deleting a file
fs.unlink('example.txt', (err) => {
    if (err) throw err;
    console.log('File deleted successfully!');
});

11. Working with Apis

In Node.Js, we can work with APIs by calling external APIs (making requests) and creating our own (APIs serving response).

Making HTTP Requests (axios, fetch)

Node.Js does not have built-in fetch() like the browser, so we used a third-party library or built-in http, module for API requests.

Using Axios

To use the axios first, we need to install the "axios" using the following command.

npm install axios

Example: GET & POST Request (Fetching/Sending Data)

const axios = require('axios');

//Get request (Fetching Data)
axios.get('https://jsonplaceholder.typicode.com/posts/1')
.then(response => {
   console.log(response.data);
})
.catch(error => {
   console.error('Error:', error.message);
});

// Post requesting (Sending Data)
axios.post('https://jsonplaceholder.typicode.com/posts', {
   title: 'New Post',
   body: 'This is a test post',
   userId: 1
})
.then(response => {
   console.log('Created Post:', response.data);
})
.catch(error => {
   console.error('Error:', error.message);
});

Using Fetch

To use the fetch first, we need to install the "fetch" using the following command.

npm install node-fetch

Example: GET & POST Request With Fetch

const fetch = require('node-fetch');

// Get Request
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error('Error:', err.message));

// POST Request
fetch('https://jsonplaceholder.typicode.com/posts', {
   method: 'POST',
   headers: { 'Content-Type': 'application/json' },
   body: JSON.stringify({
      title: 'New Post',
      body: 'This is a test post',
      userId: 1
   })
})
.then(res => res.json())
.then(data => console.log('Created Post:', data))
.catch(err => console.error('Error:', err.message));

Building REST APIs with Express.js

A REST API enables clients (frontend applications, mobile applications) to communicate with a back-end server through HTTP methods (GET, POST, PUT, DELETE).

To use the rest API, install the Express.Js first −

npm install express

Setting up express server

const express = require('express');
const app = express();
// Middleware to parse JSON data
app.use(express.json());
app.listen(3000, () => {
   console.log('Server running at http://localhost:3000/');
});

Example: Creating API Routes (CRUD Operation)

Let's create an api routs to manage the users −

const fetch = require('node-fetch');

let users = [{
      id: 1,
      name: 'Alice'
   },
   {
      id: 2,
      name: 'Bob'
   }
];

// GET - Fetch All Users
app.get('/users', (req, res) => {
   res.json(users);
});

// GET - Fetch a User by ID
app.get('/users/:id', (req, res) => {
   const user = users.find(u => u.id == req.params.id);
   user ? res.json(user) : res.status(404).send('User not found');
});

// POST - Add a New User
app.post('/users', (req, res) => {
   const newUser = {
      id: users.length + 1,
      ...req.body
   };
   users.push(newUser);
   res.status(201).json(newUser);
});

// PUT- Update a user
app.put('/users/:id', (req, res) => {
   let user = users.find(u => u.id == req.params.id);
   if (user) {
      Object.assign(user, req.body);
      res.json(user);
   } else {
      res.status(404).send('User not found');
   }
});

// Delete- Remove a User
app.delete('/users/:id', (req, res) => {
   users = users.filter(u => u.id != req.params.id);
   res.send('User deleted');
});

12. Authentication & Security

When developing web apps, authentication and security are very important. Node.Js provides various tools and libraries to secure 'APIs' and authenticate user.

JWT Authentication

The JWT stands for JSON Web Token. It is used for securely transmitting information between the client and the server. Following command install the JWT library −

npm install jsonwebtoken

Example: Generate a JWT Token (User Login)

Here, we generates a signed JWT token that expires in 1 hour −

const jwt = require('jsonwebtoken');

const user = { id: 1, username: 'admin' };
// Use env variable in production
const secretKey = 'mySecretKey';

const token = jwt.sign(user, secretKey, { expiresIn: '1h' });
console.log('JWT Token:', token);

Example: Verify a JWT Token (Middleware)

Here, we use middleware to protect routes from unauthorized access −

const authenticateJWT = (req, res, next) => {
   const token = req.header('Authorization');
   if (!token) return res.status(401).send('Access Denied');
   jwt.verify(token, secretKey, (err, user) => {
      if (err) return res.status(403).send('Invalid Token');
      req.user = user;
      next();
   });
};

Hashing Passwords with Bcrypt

We hash the password for security intents. Instead of storing plain-text passwords, we hash them. Following is the command for install bcrypt

npm install bcrypt

Example: Hash a Password

The following code, shows how to hash a password −

const bcrypt = require('bcrypt');

const password = 'mypassword';
const saltRounds = 10;

bcrypt.hash(password, saltRounds, (err, hash) => {
   if (err) throw err;
   console.log('Hashed Password:', hash);
});

Example: Verify The Password

The following code, is used to verify the password −

// Stored hash
const hashedPassword = '$2b$10$...';

bcrypt.compare('mypassword', hashedPassword, (err, result) => {
   if (result) console.log('Password Match');
   else console.log('Invalid Password');
});

Helmet & CORS for Security

The Helmet prevents security vulnerabilities. It adds security headers to protect against attacks. Cors (Cross-Origin Resource Sharing) allows APIs to accept requests from different domains.

To install the Helmet use the below command

npm install helmet

Let's see how we can use helmet to prevent common security threats −

const helmet = require('helmet');
app.use(helmet());

To install the CORS use the below command

npm install cors

Let's see how the cors prevents errors when calling APIs from different domains −

const cors = require('cors');
app.use(cors());

13. Error Handling & Debugging

Error handling prevents the application from crashing and improving user experience. Debugging helps identify and fix issues efficiently.

Try-Catch Blocks & Error Handling Middleware

The try-catch is used to handle beautifully in both synchronous and asynchronous operation. But in express we use error handling middleware to catch error globally.

Example: Handling Synchronous Errors

This code prevent app crashes due to invalid JSON parsing −

try {
   let result = JSON.parse("{invalidJson}"); // Invalid JSON
   console.log(result);
} catch (error) {
   console.error("Error occurred:", error.message);
}

Example: Express Error Handling Middleware

This example code catches errors and prevents crashes in Express applications −

const express = require('express');
const app = express();

app.get('/', (req, res) => {
   throw new Error("Something went wrong!");
});

// Error Handling Middleware
app.use((err, req, res, next) => {
   console.error("Error:", err.message);
   res.status(500).json({ message: err.message });
});

app.listen(3000, () => console.log("Server running on port 3000"));

Debugging with console.log & Debugging Tools

Using console.log is the simplest way to check values at different points in the code.

const num = 42;
console.log("Debugging Value:", num);

Debugging Tools

Node.Js Provides built-in debugging tools like Chrome dev tools and the Node.Js inspector. To run in Debug mode, use the following command −

node --inspect-brk app.js

14. Websocket & Real-time Application

Web Socket is a bidirectional, full-duplex communication protocol that enables real-time communication between a client (browser) and a server over a single, persistent connection.

Following are the key benefits of the web-sockets −

  • Real-time Communication: It is ideal for chats, notification, live updates.
  • Bi-Directional: Both client and sever can send messages
  • Persistent Connection: Reduces overhead from repeated HTTP requests.
  • Low Latency: Faster than traditional HTTP polling.

How Web-sockets Work

The following steps are for web sockets to complete their work −

  • The client sends a WebSocket handshake request using ws: or wss://(secure WebSocket)
  • Server accepts the connection and maintains an open channel.
  • Client & Server can sends message in real time without re-establishing the connection.
  • The connection stays open until either side disconnects.

Using Socket.io for Real-Time Communication

socket.io is a Node.Js library that makes WebSocket easier to implement with automatic fallback support. To install the socket.io and client communication in your project, use the below commands −

npm install socket.io

npm install socket.io-client

Setting up WebSocket Server

Create a server.js file: after implementing the below code, the server can handle a web-socket connection.

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

// Handle WebSocket connections
io.on('connection', (socket) => {
   console.log('A user connected:', socket.id);

   // Receiving a message from the client
   socket.on('message', (data) => {
      console.log('Message received:', data);
	  // Broadcast message to all clients
      io.emit('message', data);
   });

   // Handle disconnect
   socket.on('disconnect', () => {
      console.log('User disconnected:', socket.id);
   });
});

server.listen(3000, () => {
   console.log('WebSocket Server running at http://localhost:3000');
});

15. Deploying a Node.Js Application

Deploying a Node.Js application makes it available on the internet, there users can access the application easily. We can deploy your app using various platforms like Heroku, vertical, or AWS. Additionally, PM2 helps manage your Node.Js process in production.

16. Best Practise & Performance Optimization

Optimise your Node.Js applications provide faster execution, improved scalability, and security. Let's look at some major best practices and performance optimisations.

Following is the best practice for performance optimizations −

Optimization Benefits
Use Asynchronous Code (async/await, Promises) Avoids blocking the event loop
Use PM2 for Process Management Keeps the app running in production
Enable Compression (compression middleware) Reduces response size, improves speed
Use Caching (Redis, Memory Cache) Reduces database queries, speeds up response time
Use Cluster Mode (cluster module) Utilizes multiple CPU cores
Optimize Database Queries Use indexes, avoid unnecessary calls
Use Streams for Large Data Efficient handling of large files
Reduce Unused Dependencies Keeps the app lightweight

Using Environment Variables

Why we used environment variables?

We use the environment variables because they hide sensitive information like (API keys, and data credentials), easier configuration manage the environment. Keep the codebase clean.

Following is the command to install the .env file −

npm install dotenv

Create a .env File

PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASS=secret
JWT_SECRET=yoursecretkey

Load Variables in server.js

require('dotenv').config();

console.log("Server running on port:", process.env.PORT);
console.log("Database Host:", process.env.DB_HOST);

Logging With Winston

Why we use winston for logging?

We use Winston for logging because it stores logs with timestamps, supports multiple log levels (info, warn, error), and logs to files, databases, or external services.

Following is the command to install Winston −

npm install winston

Setup Winston Logger

Following is the code: Structured logging improves debugging and monitoring.

const winston = require('winston');
const logger = winston.createLogger({
   level: 'info',
   format: winston.format.json(),
   transports: [
      new winston.transports.Console(), // Logs to console
      new winston.transports.File({ filename: 'app.log' }) // Logs to a file
   ]
});

// Log messages
logger.info("Server started");
logger.warn("Low disk space warning");
logger.error("Database connection failed");

Conclusion

This Node.Js cheat sheet covered important topics that help you to design, optimize, and deploy Node.Js applications successfully. Mastering Node.Js enables you to create scalable, high-performance web applications. Whether you are developing REST APIs, real-time applications, or micro-services, sticking to best practices ensures efficiency, security, and maintainability.

Advertisements