GyanMilega

Introduction to Node.js (Full Interview Guide)

Author: Sagar Kudu
Sagar Kudu

Introduction

  • It focuses on low-level Node.js concepts without frameworks like Express, which are commonly used for building APIs and web applications.

  • The blog will explore the HTTP module and other core Node.js modules, which can be beneficial even for those with prior Node.js and Express experience.

  • Node.js is not a framework, library, or language; it is a JavaScript runtime environment built with C++ and uses the V8 JavaScript engine (also used in Google Chrome).

  • It allows building and running JavaScript applications directly on your computer or server.

  • Node.js is primarily used for server-side and networking applications, APIs, and microservices, enabling JavaScript for back-end development, similar to Python, PHP, or C#.

  • Historically, JavaScript was client-side (browser-only) for tasks like form validation and animation, but Node.js transformed it into a powerful full-stack language.

  • Other JavaScript runtimes exist (e.g., Deno, Bun.js) but are newer and lack industry adoption, community, or support compared to Node.js.

  • Node.js is fast and scalable due to its architecture and the V8 engine.

  • It is widely popular, used by millions of websites and companies like Netflix, Uber, and LinkedIn, as well as startups and smaller projects.

  • The blog will cover:

    • What Node.js is and how it works under the hood.

    • Installation and project setup, including package.json.

    • CommonJS and ES Modules.

    • Core modules like HTTP, File System (FS), Path, URL, and Events.

    • Custom middleware.

  • Prerequisites for Node.js: A good understanding of JavaScript fundamentals (variables, functions, loops, objects, classes) and asynchronous programming (callbacks, promises, async/await).

  • Familiarity with HTTP (request/response cycle, methods like GET/POST/PUT/DELETE, common status codes) and JSON APIs is also helpful.

  • Experience with NPM (Node Package Manager) from front-end frameworks like React is often common.

  • How Node.js works:

    • Built on the V8 JavaScript engine.

    • Non-blocking I/O: It doesn’t wait for input/output operations (network calls, file system, database) to complete.

    • Uses events and callbacks to handle thousands of connections concurrently, making it fast and efficient.

    • It has a single main thread that executes JavaScript code, differing from multi-threaded environments.

    • The Event Loop is a mechanism for non-blocking I/O. When an I/O operation starts, Node.js continues executing other code. Upon completion, a callback is triggered, added to the event queue, and then executed by the Event Loop.

  • What Node.js is used for:

    • Building APIs (RESTful, GraphQL).

    • Server-rendered applications (serving HTML pages using template engines like EJS, Mustache).

    • Real-time applications (chat, games, collaboration tools).

    • Microservices.

    • Command-line tools (CLIs).

    • Bots (Twitter, Slack, Discord).

    • Web scraping.

    • Web servers (sophisticated or simple static file servers).

  • What Node.js is NOT great for:

    • CPU-intensive applications (e.g., heavy computation) because it’s single-threaded and uses an event loop, which favors I/O operations. For such tasks, languages like Python, Ruby, or Java might be better suited.

      node.js introduction


2. Installation

Notes:

  • Installation is straightforward on Windows or Mac by downloading the LTS (Long-Term Support) version from nodejs.org and running the installer.

  • On Mac, Homebrew can be used.

  • On Linux, use the distribution’s package manager.

  • Verification: Open a terminal/command line and run node --version to check the installed Node.js version.

  • Node.js comes bundled with NPM (Node Package Manager), which can also be verified with npm --version.

Code (Terminal Commands):

# Check Node.js version
node --version

# Check NPM version
npm --version

3. Node REPL

Notes:

  • REPL stands for Read-Eval-Print Loop.

  • It’s a command-line environment for running JavaScript.

  • Useful for testing code snippets and experimenting with JavaScript without creating files.

Code (REPL Commands):

# Start the Node REPL
node

# Inside REPL:
console.log('Hello World');
# Output: Hello World
# Output: undefined (because console.log doesn't return a value)

let name = 'John';
# Output: undefined

console.log(name);
# Output: John

const greet = () => `Hello ${name}`;
# Output: undefined

greet();
# Output: 'Hello John'

# Exit REPL
# Press Ctrl + C (twice) or Ctrl + D (on Linux/macOS) / F6 (on Windows)

4. Setup & package.json Init

Notes:

  • Create a project folder (e.g., nodejs-crash-2024).

  • Navigate into the folder.

  • Open your text editor (e.g., VS Code) in that folder.

  • The package.json file is a manifest file for the project.

  • It’s typically the first thing initialized in a new Node.js project.

  • npm init is used to create it, asking a series of questions (package name, version, description, entry point, author, license).

  • Adding the -y flag (npm init -y) skips all questions and uses default values.

  • package.json also holds NPM scripts, which can be used to run commands like starting a server or running tests.

Code (Terminal Commands):

# Create a new directory and navigate into it
mkdir nodejs-crash-2024
cd nodejs-crash-2024

# Initialize package.json (interactive)
npm init

# Initialize package.json with defaults (non-interactive)
npm init -y

Example package.json after npm init:

{
  "name": "nodejs-crash-2024",
  "version": "1.0.0",
  "description": "Node.js crash course code",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Your Name",
  "license": "MIT"
}

5. Running JavaScript Files

Notes:

  • Create an entry point file (e.g., index.js, app.js, or server.js).

  • This file is typically where other project files are imported.

  • Run a JavaScript file using node <filename.js> in the terminal.

  • The .js extension can often be omitted.

  • Environment Differences (Browser vs. Node.js):

    • Node.js does not have a window object (browser-specific).

    • Node.js does not have a document object (no DOM).

    • Node.js has a global object, which is similar to window but represents the global Node.js environment. It includes functions like setTimeout and setInterval.

    • Node.js has a process object, representing the current Node.js process, which allows access to environment variables and other process-specific information.

Code:

index.js

console.log('Hello World from index.js');

// Trying to access browser-specific objects will result in an error
// console.log(window); // Error: window is not defined
// console.log(document); // Error: document is not defined

// Global object in Node.js
console.log(global);

// Process object in Node.js
console.log(process);

Terminal Commands:

# Run the JavaScript file
node index.js
# or
node index

6. CommonJS Modules

Notes:

  • CommonJS is the native Node.js module system.

  • It uses module.exports to export values and require() to import them.

  • You can export single values (default export) or multiple values as an object (named exports).

  • When importing with require(), the .js extension is optional.

Code:

utils.js (CommonJS Exports)

// Exporting a single function (default export)
const generateRandomNumber = () => {
    return Math.floor(Math.random() * 100) + 1;
};

module.exports = generateRandomNumber;

// To export multiple functions/data:
/*
const celsiusToFahrenheit = (celsius) => {
    return (celsius * 9) / 5 + 32;
};

module.exports = {
    generateRandomNumber,
    celsiusToFahrenheit
};
*/

index.js (CommonJS Imports)

// Import a single function
const generateRandomNumber = require('./utils');
console.log(`Random number: ${generateRandomNumber()}`);
console.log(`Random number: ${generateRandomNumber()}`);

// Import multiple functions (if exported as an object)
/*
const { generateRandomNumber, celsiusToFahrenheit } = require('./utils');
console.log(`Random number: ${generateRandomNumber()}`);
console.log(`Celsius to Fahrenheit (0C): ${celsiusToFahrenheit(0)}`); // Should be 32F
*/

Terminal Command:

node index.js

7. ES Modules

Notes:

  • ES Modules (ESM) use the import and export syntax, which is more modern and commonly used in front-end JavaScript (e.g., React, Vue).

  • To enable ES Modules in Node.js, you must add "type": "module" to your package.json file.

  • When importing local files with ES Modules in Node.js, you must include the .js extension.

  • You can use export for named exports and export default for a default export.

  • A file can have one default export and multiple named exports.

Code:

package.json (Add type: "module")

{
  "name": "nodejs-crash-2024",
  "version": "1.0.0",
  "description": "Node.js crash course code",
  "main": "index.js",
  "type": "module",  <-- Add this line
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Your Name",
  "license": "MIT"
}

postController.js (ES Module Exports)

const posts = [
    { id: 1, title: 'Post One' },
    { id: 2, title: 'Post Two' }
];

// Named export
export const getPostLength = () => {
    return posts.length;
};

// Default export
const getPosts = () => {
    return posts;
};

export default getPosts;

// Another way to do named export at the bottom (if not inline)
// export { getPostLength };

index.js (ES Module Imports)

// Import default export (no curly braces) and named export (with curly braces)
import getPosts, { getPostLength } from './postController.js'; // .js extension is required

console.log('Posts:', getPosts());
console.log('Post Length:', getPostLength());

Terminal Command:

node index.js

8. HTTP Module & Create Server

Notes:

  • The HTTP module is a core Node.js module that allows you to create servers, accept requests, and send responses.

  • While frameworks like Express simplify this, understanding the HTTP module is fundamental.

  • Import http from 'http' (no relative path needed).

  • Use http.createServer() to create a server instance. This method takes a callback function with request (req) and response (res) objects.

  • The res.write() method sends data to the client.

  • The res.end() method must be called to terminate the response stream.

  • res.end() can also send the response body directly, replacing res.write() for simple responses.

  • Use server.listen(port, callback) to make the server listen on a specific port.

  • You can set HTTP headers using res.setHeader('Header-Name', 'value'), e.g., Content-Type.

  • The res.statusCode property can be set to control the HTTP status code (e.g., 200 for OK, 404 for Not Found, 500 for Server Error).

  • res.writeHead(statusCode, headersObject) is a shortcut to set both the status code and headers in one go.

  • You can send JSON data by setting Content-Type: application/json and using JSON.stringify() on your data.

Code:

server.js

import { createServer } from 'http'; // Using ES Modules destructuring
// or import http from 'http';

const PORT = process.env.PORT || 8000; // Use environment variable for port

const server = createServer(async (req, res) => {
    // Log request URL and method (for debugging)
    console.log(`Request URL: ${req.url}, Method: ${req.method}`);

    // Set default content type to HTML and status code 200
    res.setHeader('Content-Type', 'text/html');
    res.statusCode = 200;

    // Simple routing example (will be enhanced later)
    if (req.url === '/') {
        res.end('<h1>Homepage</h1>');
    } else if (req.url === '/about') {
        res.end('<h1>About Page</h1>');
    } else if (req.url === '/api') {
        // Example of sending JSON response
        res.writeHead(200, { 'Content-Type': 'application/json' });
        res.end(JSON.stringify({ message: 'API Data' }));
    } else {
        // Not found page
        res.writeHead(404, { 'Content-Type': 'text/html' });
        res.end('<h1>404 Not Found</h1>');
    }
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Terminal Command:

# First, update package.json to run server.js
# In package.json, change "main": "server.js"
# Or update the "start" script, see next section.

# Then run:
node server.js

9. NPM Scripts

Notes:

  • NPM scripts are defined in the "scripts" section of package.json.

  • They allow you to run terminal commands using npm run <script-name>.

  • For start and test scripts, you can use npm start or npm test directly without run.

  • This makes commands easier to remember and manage.

Code:

package.json (Add a start script)

{
  "name": "nodejs-crash-2024",
  "version": "1.0.0",
  "description": "Node.js crash course code",
  "main": "server.js",
  "type": "module",
  "scripts": {
    "start": "node server.js",  <-- Add/modify this line
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Your Name",
  "license": "MIT"
}

Terminal Command:

npm start

10. NPM Modules & Nodemon

Notes:

  • NPM (Node Package Manager) allows you to install third-party packages from the npmjs.com registry.

  • Use npm install <package-name> (or npmi <package-name>) to install a package.

  • Package documentation pages on npmjs.com provide installation instructions, usage, and other details.

  • When a package is installed, a node_modules/ folder is created, containing the package and all its dependencies.

  • A package-lock.json file is also created, detailing the entire dependency tree and exact versions.

  • nodemon is a popular development dependency that automatically restarts the Node.js server whenever file changes are detected, saving manual restarts.

  • To install a package as a development dependency (not needed in production), use the -D or --save-dev flag: npm install -D nodemon.

  • Development dependencies are listed under "devDependencies" in package.json.

  • To use nodemon, update your start script in package.json to nodemon <filename.js>.

Code:

Terminal Commands:

# Install nodemon as a development dependency
npm install -D nodemon
# or
npmi -D nodemon

package.json (After nodemon installation and script update)

{
  "name": "nodejs-crash-2024",
  "version": "1.0.0",
  "description": "Node.js crash course code",
  "main": "server.js",
  "type": "module",
  "scripts": {
    "start": "nodemon server.js",  <-- Use nodemon instead of node
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Your Name",
  "license": "MIT",
  "devDependencies": {  <-- New section for dev dependencies
    "nodemon": "^3.1.0"
  }
}

Terminal Command to run with Nodemon:

npm start

11 .gitignore File

Notes:

  • The node_modules/ folder should never be pushed to a Git repository because it’s very large and can be regenerated from package.json.

  • When someone clones your repository, they simply run npm install (or npm i) to install all dependencies listed in package.json.

  • A .gitignore file (prefixed with a dot) tells Git which files or folders to ignore.

  • Create a file named .gitignore in your project root.

  • Add node_modules/ to it to prevent it from being committed.

  • It’s also good practice to add .env files here (discussed in the next section).

Code:

.gitignore

node_modules/
.env

12. - Environment Variables & .env

Notes:

  • Environment variables are system-wide variables that can be accessed by your program.

  • In Node.js, they are accessed via the process.env object.

  • Sensitive information like API keys or database credentials should not be hardcoded in your source code.

  • A .env file (environment file) is used to store these variables locally.

  • It should be added to .gitignore to prevent it from being committed to version control.

  • Recent Node.js versions allow direct loading of .env files without external packages like dotenv.

  • To load a .env file, use the --env-file flag when running Node.js: node --env-file .env <filename.js>.

  • This flag can be added to your NPM scripts in package.json.

Code:

.env

PORT=8080
API_KEY=your_secret_api_key_here

package.json (Update start script to use .env file)

{
  "name": "nodejs-crash-2024",
  "version": "1.0.0",
  "description": "Node.js crash course code",
  "main": "server.js",
  "type": "module",
  "scripts": {
    "start": "nodemon --env-file .env server.js", <-- Add --env-file flag
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Your Name",
  "license": "MIT",
  "devDependencies": {
    "nodemon": "^3.1.0"
  }
}

server.js (Accessing environment variables)

import { createServer } from 'http';

// Access PORT from process.env, with a fallback to 8000 if not set
const PORT = process.env.PORT || 8000;
// const API_KEY = process.env.API_KEY; // Example of accessing another variable

const server = createServer(async (req, res) => {
    // ... (rest of server logic)
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
    // console.log(`API Key: ${API_KEY}`); // For demonstration, don't log sensitive info in production
});

Terminal Command:

npm start

13. Req Object

Notes:

  • The request (req) object in the createServer callback provides information about the incoming HTTP request.

  • Key properties to inspect are:

    • req.url: The URL path of the request (e.g., /, /about, /api/users).

    • req.method: The HTTP method used for the request (e.g., GET, POST, PUT, DELETE).

  • These are crucial for implementing routing and determining how to respond to different requests.

  • The req object also contains other information like headers, cookies, etc..

Code:

server.js (Inside createServer callback)

import { createServer } from 'http';

const PORT = process.env.PORT || 8000;

const server = createServer(async (req, res) => {
    // Console log the request URL and method for every incoming request
    console.log(`Request URL: ${req.url}`);
    console.log(`Request Method: ${req.method}`);

    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end('<h1>Check your console for req object details!</h1>');
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Terminal Command:

npm start

Access http://localhost:8080/ or http://localhost:8080/about in your browser and observe the terminal output.


14. Marking Requests From Postman

Notes:

  • When building APIs, you often need to test different HTTP methods (GET, POST, PUT, DELETE) without a front-end client.

  • Tools like Postman (or curl, VS Code extensions) are used to send custom HTTP requests.

  • Postman allows you to specify the URL, HTTP method, headers, and request body easily.

  • Making a POST request to your server from Postman will log POST as the req.method in your Node.js console.

Steps for Postman:

  1. Open Postman (or your preferred API client).

  2. Create a new HTTP Request.

  3. Set the URL to your Node.js server (e.g., http://localhost:8080).

  4. Change the HTTP method dropdown (e.g., from GET to POST).

  5. Click “Send”.

  6. Observe the Request Method: POST in your Node.js server console.


15. Simple Routing

Notes:

  • With the core HTTP module, routing involves manually checking req.url and req.method using if/else if statements.

  • This approach becomes cumbersome for complex applications, highlighting the value of frameworks like Express.

  • You can define different responses based on the requested URL.

  • An else block can serve as a “not found” handler.

  • It’s important to set the appropriate res.statusCode (e.g., 404 for not found) and Content-Type for each route.

Code:

server.js

import { createServer } from 'http';

const PORT = process.env.PORT || 8000;

const server = createServer(async (req, res) => {
    console.log(`Request URL: ${req.url}, Method: ${req.method}`);

    // Set default HTML content type
    res.setHeader('Content-Type', 'text/html');

    if (req.method === 'GET') { // Check for GET requests only
        if (req.url === '/') {
            res.statusCode = 200;
            res.end('<h1>Homepage</h1>');
        } else if (req.url === '/about') {
            res.statusCode = 200;
            res.end('<h1>About Page</h1>');
        } else {
            res.statusCode = 404;
            res.end('<h1>404 Not Found</h1>');
        }
    } else {
        // Handle non-GET requests (e.g., POST, PUT, DELETE)
        res.statusCode = 405; // Method Not Allowed
        res.setHeader('Content-Type', 'text/plain');
        res.end('Method Not Allowed');
    }
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Terminal Command:

npm start

Test different URLs (/, /about, /test) and methods (GET, POST using Postman) to observe routing.


16. Loading Files

Notes:

  • Instead of embedding HTML directly in res.end(), it’s more practical to load HTML files.

  • The fs (File System) module is used for interacting with the file system.

  • It’s recommended to use the promise-based version of fs (fs/promises) for async/await syntax, which is non-blocking.

  • For ES Modules, __filename and __dirname (available in CommonJS) are not directly accessible.

  • You can construct __filename and __dirname using the url module (URL.fileURLToPath(import.meta.url)) and the path module (path.dirname()).

  • The path.join() method is useful for constructing file paths reliably across different operating systems.

Code:

1. Create a public folder and HTML files:

public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Homepage</title>
</head>
<body>
    <h1>Welcome to the Homepage!</h1>
</body>
</html>

public/about.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>About Us</title>
</head>
<body>
    <h1>About Our Project</h1>
</body>
</html>

2. Update server.js:

server.js

import { createServer } from 'http';
import * as fs from 'fs/promises'; // Import promise-based fs module
import * as url from 'url';      // Import url module
import * as path from 'path';     // Import path module

const PORT = process.env.PORT || 8000;

// Construct __filename and __dirname for ES Modules
const __filename = url.fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// console.log(__filename); // Example output: /path/to/your/project/server.js
// console.log(__dirname);  // Example output: /path/to/your/project

const server = createServer(async (req, res) => {
    console.log(`Request URL: ${req.url}, Method: ${req.method}`);

    // Ensure status code is set by default or in specific routes
    res.setHeader('Content-Type', 'text/html');

    if (req.method === 'GET') {
        let filePath;
        if (req.url === '/') {
            filePath = path.join(__dirname, 'public', 'index.html');
        } else if (req.url === '/about') {
            filePath = path.join(__dirname, 'public', 'about.html');
        } else {
            // No specific file path found, throw error for 404
            res.statusCode = 404;
            res.end('<h1>404 Not Found</h1>');
            return; // Important to return after res.end
        }

        try {
            const data = await fs.readFile(filePath, 'utf8');
            res.statusCode = 200;
            res.end(data);
        } catch (error) {
            console.error('Error loading file:', error);
            res.statusCode = 500;
            res.end('<h1>500 Server Error</h1>');
        }
    } else {
        res.statusCode = 405;
        res.setHeader('Content-Type', 'text/plain');
        res.end('Method Not Allowed');
    }
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Terminal Command:

npm start

Access http://localhost:8080/ and http://localhost:8080/about to see the loaded HTML files.


17. Building a Simple API

Notes:

  • APIs typically involve handling specific HTTP methods (GET, POST, PUT, DELETE) for different resources (e.g., /api/users).

  • Responses for APIs are often in JSON format, requiring Content-Type: application/json and JSON.stringify() for outgoing data.

  • When retrieving a single resource by ID (e.g., /api/users/1), you need to parse the ID from req.url.

  • Regular expressions (RegExp.prototype.test() or String.prototype.match()) can be used to match dynamic URL patterns like /api/users/:id.

  • It’s important to return appropriate HTTP status codes (e.g., 200 OK, 404 Not Found) for API responses.

Code:

1. Create server2.js and update package.json to run it.

package.json (Change start script)

{
  "name": "nodejs-crash-2024",
  "version": "1.0.0",
  "description": "Node.js crash course code",
  "main": "server2.js", // Change main entry point
  "type": "module",
  "scripts": {
    "start": "nodemon --env-file .env server2.js", // Update script
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Your Name",
  "license": "MIT",
  "devDependencies": {
    "nodemon": "^3.1.0"
  }
}

server2.js

import { createServer } from 'http';

const PORT = process.env.PORT || 8000;

const users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' },
    { id: 3, name: 'Jim Bob' }
];

const server = createServer(async (req, res) => {
    console.log(`Request URL: ${req.url}, Method: ${req.method}`);

    // Set default content type for API
    res.setHeader('Content-Type', 'application/json');

    // GET /api/users - Get all users
    if (req.url === '/api/users' && req.method === 'GET') {
        res.statusCode = 200;
        res.end(JSON.stringify(users));
    }
    // GET /api/users/:id - Get single user by ID
    else if (req.url.match(/\/api\/users\/(+)/) && req.method === 'GET') {
        const id = parseInt(req.url.split('/')); // Extract ID from URL
        const user = users.find(u => u.id === id);

        if (user) {
            res.statusCode = 200;
            res.end(JSON.stringify(user));
        } else {
            res.statusCode = 404;
            res.end(JSON.stringify({ message: 'User not found' }));
        }
    }
    // Handle other requests/routes not found
    else {
        res.statusCode = 404;
        res.end(JSON.stringify({ message: 'Route not found' }));
    }
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Terminal Command:

npm start

Use Postman or your browser to test: * GET http://localhost:8080/api/users (get all users) * GET http://localhost:8080/api/users/1 (get user with ID 1) * GET http://localhost:8080/api/users/100 (get non-existent user) * GET http://localhost:8080/api/todos (non-existent route)


18. Middleware

Notes:

  • Middleware functions are functions that have access to the request (req) and response (res) objects.

  • They sit between incoming requests and outgoing responses.

  • They can execute any code, make changes to req and res objects (e.g., adding a user property for authentication), and must eventually call the next() function.

  • next() passes control to the next middleware function in the stack or the route handler.

  • Middleware is usually organized in separate files for reusability.

Code:

server2.js (Add a logger middleware)

import { createServer } from 'http';

const PORT = process.env.PORT || 8000;

const users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' },
    { id: 3, name: 'Jim Bob' }
];

// Logger Middleware
const logger = (req, res, next) => {
    console.log(`${req.method} ${req.url}`); // Log method and URL
    next(); // Pass control to the next middleware or route handler
};

const server = createServer(async (req, res) => {
    // Apply middleware - the entire routing logic will be wrapped inside the logger's callback
    logger(req, res, () => {
        // Set default content type for API
        res.setHeader('Content-Type', 'application/json');

        // GET /api/users - Get all users
        if (req.url === '/api/users' && req.method === 'GET') {
            res.statusCode = 200;
            res.end(JSON.stringify(users));
        }
        // GET /api/users/:id - Get single user by ID
        else if (req.url.match(/\/api\/users\/(+)/) && req.method === 'GET') {
            const id = parseInt(req.url.split('/'));
            const user = users.find(u => u.id === id);

            if (user) {
                res.statusCode = 200;
                res.end(JSON.stringify(user));
            } else {
                res.statusCode = 404;
                res.end(JSON.stringify({ message: 'User not found' }));
            }
        }
        // Handle other requests/routes not found
        else {
            res.statusCode = 404;
            res.end(JSON.stringify({ message: 'Route not found' }));
        }
    });
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Terminal Command:

npm start

Make requests and observe the logger output in the terminal before the API response.


19. Cleanup (Middleware & Handlers)

Notes:

  • To make the server code cleaner and more scalable, separate middleware functions and route handlers can be created.

  • Middleware can handle common tasks like setting Content-Type for all API routes.

  • Handler functions encapsulate the logic for specific routes, taking req and res as arguments.

  • Middleware can be “stacked” by nesting their callbacks, with next() passing control from one to the next.

Code:

server2.js (Refactored with middleware and handlers)

import { createServer } from 'http';

const PORT = process.env.PORT || 8000;

const users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' },
    { id: 3, name: 'Jim Bob' }
];

// Middleware 1: Logger
const logger = (req, res, next) => {
    console.log(`${req.method} ${req.url}`);
    next(); // Pass control to the next middleware
};

// Middleware 2: JSON Header
const jsonMiddleware = (req, res, next) => {
    res.setHeader('Content-Type', 'application/json');
    next(); // Pass control to the next middleware or handler
};

// Handler 1: Get all users
const getUsersHandler = (req, res) => {
    res.statusCode = 200;
    res.end(JSON.stringify(users));
};

// Handler 2: Get user by ID
const getUserByIdHandler = (req, res) => {
    const id = parseInt(req.url.split('/'));
    const user = users.find(u => u.id === id);

    if (user) {
        res.statusCode = 200;
        res.end(JSON.stringify(user));
    } else {
        res.statusCode = 404;
        res.end(JSON.stringify({ message: 'User not found' }));
    }
};

// Handler 3: Not Found
const notFoundHandler = (req, res) => {
    res.statusCode = 404;
    res.end(JSON.stringify({ message: 'Route not found' }));
};

const server = createServer(async (req, res) => {
    // Stack middleware
    logger(req, res, () => {
        jsonMiddleware(req, res, () => {
            // Routing logic using handlers
            if (req.url === '/api/users' && req.method === 'GET') {
                getUsersHandler(req, res);
            } else if (req.url.match(/\/api\/users\/(+)/) && req.method === 'GET') {
                getUserByIdHandler(req, res);
            } else {
                notFoundHandler(req, res);
            }
        });
    });
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Terminal Command:

npm start

The functionality remains the same, but the code structure is much cleaner.


20. Get Req Body For POST

Notes:

  • Getting data from a POST request body (e.g., JSON payload) is more involved with the core HTTP module than with frameworks like Express.

  • The request object is an Event Emitter.

  • You need to listen for two events on the req object:

    • 'data': This event fires when chunks of data are received. You need to append these chunks to a buffer or string.

    • 'end': This event fires when the entire request body has been received. At this point, the complete data can be processed.

  • The received data is typically a string (often JSON), which needs to be parsed using JSON.parse() to convert it into a JavaScript object.

  • For successful creation, an HTTP status code of 201 (Created) is appropriate.

  • The new resource is usually sent back in the response body.

Code:

server2.js (Add createUserHandler and integrate into routing)

import { createServer } from 'http';

const PORT = process.env.PORT || 8000;

const users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' },
    { id: 3, name: 'Jim Bob' }
];

// Middleware 1: Logger
const logger = (req, res, next) => {
    console.log(`${req.method} ${req.url}`);
    next();
};

// Middleware 2: JSON Header
const jsonMiddleware = (req, res, next) => {
    res.setHeader('Content-Type', 'application/json');
    next();
};

// Handler 1: Get all users
const getUsersHandler = (req, res) => {
    res.statusCode = 200;
    res.end(JSON.stringify(users));
};

// Handler 2: Get user by ID
const getUserByIdHandler = (req, res) => {
    const id = parseInt(req.url.split('/'));
    const user = users.find(u => u.id === id);

    if (user) {
        res.statusCode = 200;
        res.end(JSON.stringify(user));
    } else {
        res.statusCode = 404;
        res.end(JSON.stringify({ message: 'User not found' }));
    }
};

// Handler 3: Create a new user (POST request)
const createUserHandler = (req, res) => {
    let body = '';
    // Listen for data chunks
    req.on('data', (chunk) => {
        body += chunk.toString(); // Append chunks and convert to string
    });

    // Listen for the end of the request
    req.on('end', () => {
        try {
            const newUser = JSON.parse(body); // Parse JSON string to object
            newUser.id = users.length + 1; // Assign a simple ID
            users.push(newUser); // Add to in-memory users array
            res.statusCode = 201; // 201 Created
            res.end(JSON.stringify(newUser)); // Send back the created user
        } catch (error) {
            console.error('Error parsing request body:', error);
            res.statusCode = 400; // Bad Request
            res.end(JSON.stringify({ message: 'Invalid JSON in request body' }));
        }
    });
};

// Handler 4: Not Found
const notFoundHandler = (req, res) => {
    res.statusCode = 404;
    res.end(JSON.stringify({ message: 'Route not found' }));
};

const server = createServer(async (req, res) => {
    logger(req, res, () => {
        jsonMiddleware(req, res, () => {
            // Routing logic
            if (req.url === '/api/users' && req.method === 'GET') {
                getUsersHandler(req, res);
            } else if (req.url.match(/\/api\/users\/(+)/) && req.method === 'GET') {
                getUserByIdHandler(req, res);
            }
            // Add POST request handler for /api/users
            else if (req.url === '/api/users' && req.method === 'POST') {
                createUserHandler(req, res);
            }
            else {
                notFoundHandler(req, res);
            }
        });
    });
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

Terminal Command:

npm start

Use Postman to test: * Method: POST * URL: http://localhost:8080/api/users * Headers: Content-Type: application/json * Body (raw, JSON): json { "name": "Brad Traversy" } * Then, make a GET request to http://localhost:8080/api/users to see the newly added user (in memory).


21. File System Module

Notes:

  • The fs (File System) module provides methods for interacting with the file system (reading, writing, appending files, creating directories, etc.).

  • Methods often come in three versions:

    1. Asynchronous (callback-based): Non-blocking, takes a callback with (err, data).

    2. Synchronous: Blocking, waits for the operation to complete before continuing execution. Generally discouraged for large operations.

    3. Promise-based: Non-blocking, uses fs/promises import, allows then().catch() or async/await syntax. This is often preferred for modern Node.js development.

  • fs.readFile(path, encoding, callback): Reads the content of a file.

  • fs.readFileSync(path, encoding): Synchronous version of readFile.

  • fs.promises.readFile(path, encoding): Promise-based version of readFile.

  • fs.writeFile(path, data, encoding, callback): Writes data to a file. It will overwrite the file if it exists.

  • fs.promises.writeFile(path, data, encoding): Promise-based version of writeFile.

  • fs.appendFile(path, data, encoding, callback): Appends data to a file without overwriting.

  • fs.promises.appendFile(path, data, encoding): Promise-based version of appendFile.

  • \n can be used to add a new line when appending text.

Code:

test.txt

This is from the text file.

fsdemo.js

// Import promise-based fs for async/await
import * as fs from 'fs/promises';
// import * as fs from 'fs'; // For callback and sync versions

// --- 1. readFile (Promise version with async/await - preferred) ---
const readFileAsyncAwait = async () => {
    try {
        const data = await fs.readFile('./test.txt', 'utf8');
        console.log('Read File (Async/Await):', data);
    } catch (error) {
        console.error('Error reading file (Async/Await):', error);
    }
};

// --- 2. writeFile (Promise version with async/await) ---
const writeFileAsyncAwait = async () => {
    try {
        await fs.writeFile('./test.txt', 'Hello, I am writing to this file.\n', 'utf8');
        console.log('File written to.');
    } catch (error) {
        console.error('Error writing file:', error);
    }
};

// --- 3. appendFile (Promise version with async/await) ---
const appendFileAsyncAwait = async () => {
    try {
        await fs.appendFile('./test.txt', 'This is appended text.\n', 'utf8');
        console.log('File appended to.');
    } catch (error) {
        console.error('Error appending file:', error);
    }
};

const runFsDemo = async () => {
    await writeFileAsyncAwait(); // Overwrite file
    await appendFileAsyncAwait(); // Append text
    await readFileAsyncAwait();   // Read updated file

    // --- Optional: Callback-based readFile ---
    // console.log('\n--- Callback-based readFile ---');
    // fs.readFile('./test.txt', 'utf8', (err, data) => {
    //     if (err) throw err;
    //     console.log('Read File (Callback):', data);
    // });

    // --- Optional: Synchronous readFile ---
    // console.log('\n--- Synchronous readFile ---');
    // try {
    //     const dataSync = fs.readFileSync('./test.txt', 'utf8');
    //     console.log('Read File (Sync):', dataSync);
    // } catch (error) {
    //     console.error('Error reading file (Sync):', error);
    // }

    // --- Optional: Promise.then based readFile ---
    // console.log('\n--- Promise .then based readFile ---');
    // fs.readFile('./test.txt', 'utf8')
    //     .then(data => console.log('Read File (Promise.then):', data))
    //     .catch(err => console.error('Error reading file (Promise.then):', err));
};

runFsDemo();

Terminal Command:

node fsdemo.js

Observe how test.txt content changes.


22. Path Module

Notes:

  • The path module provides utilities for working with file and directory paths.

  • It helps handle path segments and delimiters correctly across different operating systems (e.g., / on Linux/Mac, \ on Windows).

  • path.basename(pathString): Returns the last portion of a path (e.g., filename with extension).

  • path.dirname(pathString): Returns the directory name of a path.

  • path.extname(pathString): Returns the extension of the path.

  • path.parse(pathString): Returns an object with properties for root, dir, base, ext, and name.

  • path.join(...segments): Joins all given path segments together, normalizing the resulting path.

  • path.resolve(...segments): Resolves a sequence of paths or path segments into an absolute path.

  • As noted earlier, __filename and __dirname for ES Modules need to be constructed using url.fileURLToPath(import.meta.url) and path.dirname().

Code:

pathdemo.js

import * as path from 'path';
import * as url from 'url';

// Define a sample file path for demonstration
const filePath = '/dir1/dir2/test.txt';

// --- path.basename() ---
console.log('Basename:', path.basename(filePath)); // Output: test.txt

// --- path.dirname() ---
console.log('Dirname:', path.dirname(filePath)); // Output: /dir1/dir2

// --- path.extname() ---
console.log('Extname:', path.extname(filePath)); // Output: .txt

// --- path.parse() ---
console.log('Parse:', path.parse(filePath));
/* Output:
{
  root: '/',
  dir: '/dir1/dir2',
  base: 'test.txt',
  ext: '.txt',
  name: 'test'
}
*/

// --- Constructing __filename and __dirname for ES Modules ---
const __filename = url.fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
console.log('__filename (ESM):', __filename); // E.g., /path/to/project/pathdemo.js
console.log('__dirname (ESM):', __dirname);   // E.g., /path/to/project

// --- path.join() ---
// Joins path segments, handles platform-specific delimiters
const filePath2 = path.join(__dirname, 'subfolder', 'another_subfolder', 'myFile.log');
console.log('Join:', filePath2); // E.g., /path/to/project/subfolder/another_subfolder/myFile.log

// --- path.resolve() ---
// Resolves to an absolute path, useful for ensuring absolute paths
const filePath3 = path.resolve(__dirname, '..', 'temp', 'data.json');
console.log('Resolve:', filePath3); // E.g., /path/to/temp/data.json (goes up one level, then into temp)

Terminal Command:

node pathdemo.js

23. OS Module

Notes:

  • The os (Operating System) module provides methods for interacting with the operating system on which Node.js is running.

  • It can give information about memory, CPUs, user info, and more.

  • os.userInfo(): Returns information about the current user, including UID, GID, and username.

  • os.totalmem(): Returns the total amount of system memory in bytes.

  • os.freemem(): Returns the amount of free system memory in bytes.

  • os.cpus(): Returns an array of objects containing information about each CPU/core installed in the system.

Code:

osdemo.js

import * as os from 'os';

// --- os.userInfo() ---
console.log('User Info:', os.userInfo());
// Output: { uid: ..., gid: ..., username: 'Brad Traversy', homedir: '...', shell: '...' }
console.log('Username:', os.userInfo().username);

// --- os.totalmem() ---
console.log('Total Memory (bytes):', os.totalmem());
// Output: E.g., 17094074368 (bytes)

// --- os.freemem() ---
console.log('Free Memory (bytes):', os.freemem());
// Output: E.g., 9012345678 (bytes)

// --- os.cpus() ---
console.log('CPUs:', os.cpus());
/* Output (example for a single core):
[
  {
    model: 'Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz',
    speed: 2808,
    times: { user: 123456, nice: 0, sys: 78910, idle: 112233, irq: 456 }
  }
  ... (more objects for more cores)
]
*/

Terminal Command:

node osdemo.js

24. URL Module

Notes:

  • The url module provides utilities for URL resolution and parsing.

  • It can parse a URL string into a URL object, making its components easily accessible.

  • new URL(url_string): Creates a URL object from a string. The object includes properties like href, origin, protocol, host, pathname, search, and searchParams.

  • URL.format(url_object): Converts a URL object back into a formatted URL string.

  • import.meta.url: A special variable (not part of the url module but related) that provides the file URL of the current module. Useful for constructing __filename in ES Modules.

  • URL.fileURLToPath(fileURL): Converts a file URL (e.g., file:///path/to/file.js) to a platform-specific file path (e.g., /path/to/file.js).

  • URLSearchParams: An object available on the URL object (via url.searchParams) or creatable with new URLSearchParams(queryString). It provides methods to manipulate query parameters.

    • params.get(name): Gets the first value associated with the given search parameter.

    • params.append(name, value): Adds a new search parameter or appends a value to an existing one.

    • params.delete(name): Deletes all occurrences of a search parameter.

Code:

urldemo.js

import * as url from 'url';
import * as path from 'path'; // For fileURLToPath example

// --- 1. Construct a URL string ---
const urlString = 'https://www.google.com/search?q=hello+world&limit=10';
console.log('Original URL String:', urlString);

// --- 2. Create a URL object ---
const urlObj = new url.URL(urlString);
console.log('URL Object:', urlObj);
/* Output includes properties like:
  href: 'https://www.google.com/search?q=hello+world&limit=10',
  origin: 'https://www.google.com',
  protocol: 'https:',
  host: 'www.google.com',
  pathname: '/search',
  search: '?q=hello+world&limit=10',
  searchParams: URLSearchParams { 'q' => 'hello world', 'limit' => '10' }
*/

console.log('Pathname:', urlObj.pathname);   // Output: /search
console.log('Host:', urlObj.host);           // Output: www.google.com

// --- 3. Format URL object back to string ---
console.log('Formatted URL:', url.format(urlObj));

// --- 4. import.meta.url & URL.fileURLToPath ---
console.log('import.meta.url:', import.meta.url);
// Output: file:///path/to/your/project/urldemo.js (varies by system)

console.log('File URL to Path:', url.fileURLToPath(import.meta.url));
// Output: /path/to/your/project/urldemo.js (platform-specific path)

// --- 5. Working with URLSearchParams ---
const params = urlObj.searchParams;
console.log('Search Params (initial):', params); // URLSearchParams { 'q' => 'hello world', 'limit' => '10' }

console.log('Get "q" parameter:', params.get('q')); // Output: hello world

params.append('category', 'webdev'); // Add a new parameter
console.log('Search Params (after append):', params); // URLSearchParams { 'q' => 'hello world', 'limit' => '10', 'category' => 'webdev' }

params.delete('limit'); // Delete a parameter
console.log('Search Params (after delete):', params); // URLSearchParams { 'q' => 'hello world', 'category' => 'webdev' }

// Loop through parameters
console.log('Looping through params:');
for (const [key, value] of params.entries()) {
  console.log(`${key}: ${value}`);
}
/* Output:
q: hello world
category: webdev
*/

Terminal Command:

node urldemo.js

24. Crypto Module

Notes:

  • The crypto module provides cryptographic functionality.

  • It can be used for hashing data (e.g., passwords), generating random strings, and encrypting/decrypting data.

  • Hashing: One-way transformation of data. Useful for storing passwords securely (never store plain text passwords).

    • crypto.createHash(algorithm): Creates a Hash object. Common algorithms are sha256, md5.

    • hash.update(data): Updates the hash content.

    • hash.digest(encoding): Calculates the digest of all updated data and returns it. encoding can be 'hex', 'base64', etc..

  • Random Bytes: Generates cryptographically strong pseudo-random data.

    • crypto.randomBytes(size, callback): Generates a buffer of random bytes. The callback receives (err, buffer). The buffer can be converted to a hexadecimal string using buffer.toString('hex'). Useful for unique IDs or salts.

  • Encryption/Decryption: Transforms plaintext into ciphertext (unreadable) and back using an algorithm, a key, and an Initialization Vector (IV).

    • Algorithm: Specifies the encryption method (e.g., aes-256-cbc).

    • Key: A secret value used in encryption and decryption. Must be kept secure.

    • IV (Initialization Vector): A non-secret, random value used to ensure that encrypting the same plaintext with the same key produces different ciphertext each time, enhancing security.

    • crypto.createCipheriv(algorithm, key, iv): Creates a Cipher object for encryption.

    • cipher.update(plaintext, input_encoding, output_encoding): Encrypts data.

    • cipher.final(output_encoding): Returns any remaining encrypted data.

    • crypto.createDecipheriv(algorithm, key, iv): Creates a Decipher object for decryption.

    • decipher.update(ciphertext, input_encoding, output_encoding): Decrypts data.

    • decipher.final(output_encoding): Returns any remaining decrypted data.

Code:

cryptodemo.js

import * as crypto from 'crypto';

// --- 1. Create a Hash ---
console.log('--- Hashing ---');
const password = 'password1234';
const hash = crypto.createHash('sha256'); // Using SHA-256 algorithm
hash.update(password);
const hashedPassword = hash.digest('hex');
console.log('Original Password:', password);
console.log('Hashed Password:', hashedPassword);

// --- 2. Generate Random Bytes ---
console.log('\n--- Random Bytes ---');
crypto.randomBytes(16, (err, buffer) => { // Generate 16 random bytes
    if (err) throw err;
    console.log('Random Hex String:', buffer.toString('hex')); // Convert buffer to hex string
});

// --- 3. Encrypt and Decrypt Data ---
console.log('\n--- Encryption & Decryption ---');

const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32); // 32 bytes for AES-256
const iv = crypto.randomBytes(16);  // 16 bytes for IV

const plaintext = 'Hello, this is a secret message!';
console.log('Plaintext:', plaintext);

// Encryption
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log('Encrypted (Ciphertext):', encrypted);

// Decryption
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log('Decrypted (Plaintext):', decrypted);

Terminal Command:

node cryptodemo.js

25. Emitting Events

Notes:

  • The events module provides the EventEmitter class, which allows you to create and handle custom events.

  • It’s fundamental for building real-time applications and implementing the observer pattern.

  • import { EventEmitter } from 'events';: Imports the EventEmitter class.

  • new EventEmitter(): Creates an instance of the event emitter.

  • emitter.on(eventName, listenerFunction): Registers an event listener. The listenerFunction will be called when eventName is emitted.

  • emitter.emit(eventName, [arg1], [arg2], ...): Emits an event, triggering all registered listeners for that eventName. Any additional arguments are passed to the listener functions.

  • You can pass data as arguments when emitting an event, which the listener function receives.

  • The EventEmitter also supports an 'error' event. If an error event is emitted and no listener is registered for it, Node.js will throw an uncaught error and crash the application. It’s good practice to always handle 'error' events for robustness.

Code:

eventsdemo.js

import { EventEmitter } from 'events';

// --- 1. Create an emitter instance ---
const myEmitter = new EventEmitter();

// --- 2. Create listener functions ---
const greetHandler = (name) => {
    console.log(`Hello, ${name}!`);
};

const goodbyeHandler = (name) => {
    console.log(`Goodbye, ${name}!`);
};

// --- 3. Register event listeners ---
myEmitter.on('greet', greetHandler);
myEmitter.on('goodbye', goodbyeHandler);

// --- 4. Emit events ---
console.log('--- Emitting Events ---');
myEmitter.emit('greet', 'John');     // Emits 'greet' event, passing 'John' as data
myEmitter.emit('goodbye', 'Jane');   // Emits 'goodbye' event, passing 'Jane' as data

// --- 5. Handling errors with 'error' event ---
myEmitter.on('error', (err) => {
    console.error('An error occurred:', err.message);
    // console.error('Stack trace:', err.stack); // Optionally log stack trace
});

console.log('\n--- Emitting Error Event ---');
myEmitter.emit('error', new Error('Something went wrong during event processing!'));

// Example: Emitting a non-existent event (no listener, no error)
myEmitter.emit('unknownEvent', 'data'); // This will do nothing as no listener is registered

Terminal Command:

node eventsdemo.js

26. Process Object

Notes:

  • The process object is a global object in Node.js, meaning you don’t need to import it.

  • It provides information about, and control over, the current Node.js process.

  • process.argv: An array containing the command-line arguments passed when the Node.js process was launched.

    • The first element is node’s executable path.

    • The second element is the path to the executed JavaScript file.

    • Subsequent elements are any additional arguments.

    • Useful for building Command Line Interfaces (CLIs).

  • process.env: An object containing the user’s environment variables. We used this earlier for PORT and API_KEY from the .env file.

  • process.pid: The Process ID (PID) of the current Node.js process.

  • process.cwd(): A function that returns the current working directory of the Node.js process.

  • process.title: The string that represents the title of the Node.js process. Default is node.

  • process.memoryUsage(): A function that returns an object describing the memory usage of the Node.js process in bytes.

  • process.uptime(): Returns the number of seconds the current Node.js process has been running. (Distinct from os.uptime() which is system uptime).

  • process.exit(code): Terminates the Node.js process immediately.

    • 0: Indicates successful completion.

    • 1: Indicates a general error or unhandled exception.

    • Any code after process.exit() will not be executed.

  • process.on(eventName, listenerFunction): Registers listeners for process-specific events, such as 'exit'.

Code:

processdemo.js

// --- 1. process.argv (Command Line Arguments) ---
console.log('--- process.argv ---');
console.log('All arguments:', process.argv);
// To run: node processdemo.js --flag value
// Output will include: ['/path/to/node', '/path/to/processdemo.js', '--flag', 'value']

console.log('Specific argument (e.g., --flag):', process.argv);

// --- 2. process.env (Environment Variables) ---
console.log('\n--- process.env ---');
// console.log('All environment variables:', process.env); // Can be very long
console.log('User Name (LOGNAME/USER):', process.env.LOGNAME || process.env.USER); // Example
console.log('Path variable:', process.env.PATH);

// --- 3. process.pid (Process ID) ---
console.log('\n--- process.pid ---');
console.log('Process ID:', process.pid);

// --- 4. process.cwd() (Current Working Directory) ---
console.log('\n--- process.cwd() ---');
console.log('Current Working Directory:', process.cwd());

// --- 5. process.title (Process Title) ---
console.log('\n--- process.title ---');
console.log('Process Title:', process.title);

// --- 6. process.memoryUsage() ---
console.log('\n--- process.memoryUsage() ---');
console.log('Memory Usage:', process.memoryUsage());
/* Output:
{
  rss: 20641792,  // Resident Set Size: total memory allocated for the process
  heapTotal: 5040128, // V8 Heap total size
  heapUsed: 3230680, // V8 Heap used size
  external: 1042784, // Memory used by C++ objects bound to JavaScript objects
  arrayBuffers: 18764 // Memory used by ArrayBuffer and SharedArrayBuffer instances
}
*/

// --- 7. process.uptime() ---
console.log('\n--- process.uptime() ---');
console.log('Process Uptime (seconds):', process.uptime());

// --- 8. process.on('exit') (Event Listener for process exit) ---
console.log('\n--- process.on("exit") ---');
process.on('exit', (code) => {
    console.log(`About to exit with code: ${code}`);
});

// --- 9. process.exit() (Exiting the process) ---
// Note: Any code after process.exit() will NOT be executed.
// Uncomment to test:
// console.log('\n--- process.exit() ---');
// process.exit(0); // Exit successfully

console.log('This message will be logged before process.exit() is called (if uncommented).');

Terminal Command:

# Run without extra arguments
node processdemo.js

# Run with extra arguments
node processdemo.js --user brad

Powered by wisp

Related Posts

JavaScript Loops Explained with Examples | For Loop

Learn how loops work in JavaScript with beginner-friendly examples. This complete guide covers for loops, while loops, and practical use cases like printing messages, iterating arrays, and filtering even/odd numbers.

Read Full Story

What is JavaScript? A Complete Beginner's Guide

Learn what JavaScript is, how it works, and how to add it to your web pages with inline, external, async, and defer script loading strategies.

Read Full Story

What is a Function in JavaScript? | Function Examples & Guide

Functions in a JavaScript. Learn what functions are in JavaScript with examples. This beginner-friendly guide covers function declarations, parameters, return values, and more.

Read Full Story

Why Do Front-End Frameworks Exist?

Modern frameworks like React, Vue, and Angular exist because building complex, interactive apps with just plain JavaScript quickly becomes unmanageable. Let’s look at how web development evolved and why frameworks are the solution.

Read Full Story
Loading...
© Gyan Milega 2025