Table of contents
- What is Node JS?
- Why use Node JS?
- Cons of using Node JS
- How does Node JS work?
- Why Node JS is single-threaded?
- What is npm?
- What are modules in Node JS?
- Emitters in Node JS
- What is package.json
- What is a callback hell?
- Explain the concept of middleware
- What is REPL
- What are streams in Node JS
- What are two types of API functions in Node JS
- What is libuv
- What is the purpose of NODE_ENV
- Can DOM be accessed in Node JS?
- What is ESlint?
- What is a Passport in Node JS?
- Does Node JS provide any debugger?
- Is Cryptography supported in Node JS?
- Why does Google use the V8 engine for Node JS?
What is Node JS?
Node.js is an open-source, server-side JavaScript runtime environment that allows developers to run JavaScript code on the server. It is built on the V8 JavaScript engine, which is developed by Google for use in web browsers. Node.js enables non-blocking, event-driven architecture, making it well-suited for building highly scalable and efficient network applications.
Non-Blocking I/O: Node.js is known for its ability to handle many concurrent connections without blocking the execution of other code. This enables efficient handling of I/O operations, such as reading and writing to files, making network requests, and accessing databases.
Event-Driven Architecture: Node.js uses an event-driven, asynchronous model, where it listens for events and triggers associated callback functions when events occur. This design pattern is essential for handling concurrent connections and real-time applications.
Why use Node JS?
Node js enables consistent use of Javascript for both server-side and client-side development
Node js efficiently handles numerous concurrent connections without blocking, making it ideal for I/O-intensive tasks
It gives High Performance
It is Highly Scalable
It can excel in creating low-latency real-time applications like chat and online gaming.
Cons of using Node JS
Single-Threaded: Node.js is single-threaded, which means it might not be the best choice for CPU-intensive tasks.
Callback Hell: When handling many asynchronous operations, Node.js code can become deeply nested with callbacks, leading to the "Callback Hell" or "Pyramid of Doom" issue. This can affect code readability and maintainability.
Not Ideal for Heavy Computation: If your application requires heavy computational tasks, Node.js might not be the best choice due to its single-threaded nature. Other languages like Python or Java might be more suitable.
How does Node JS work?
Node.js is built on an event-driven, non-blocking architecture. It uses an event loop to manage and prioritize tasks. When a function is called, it's added to the call stack, executed, and removed. For non-blocking operations, like I/O tasks, Node.js initiates them and continues processing other tasks while they're in progress. Callback functions handle the results of these asynchronous operations and are placed in the event queue. The event loop continuously checks the event queue for pending callbacks and processes them, allowing Node.js to efficiently handle multiple tasks without blocking the entire process. This makes it highly suitable for real-time applications and APIs, as well as I/O-intensive tasks.
Why Node JS is single-threaded?
A single-threaded process is the execution of programmed instructions in a single sequence, A single-threaded architecture simplifies the development and debugging process. There are no concerns about thread synchronization or race conditions making it easier for developers to reason about their code.
What is npm?
npm stands for Node Package Manager, responsible for managing all the packages and modules of Node JS, If provides two main functionality
Provides online repositories for Node JS packages/modules
Provides command line utility to install Node JS packages and also manages Node JS versions and dependencies
What are modules in Node JS?
Modules in Node.js serve as self-contained units that encapsulate functionality, making them reusable across different parts of an application.
There are two types of Modules Internal and External, There are various external modules that can be installed in a node application through npm available on the internet, Some of the important internal modules are mentioned below
path
const path = require('path') //base file name console.log(path.basename(__filename)) //directory name console.log(path.dirname(__filename)) //file extension console.log(path.extname(__filename)) //Create path object console.log(path.parse(__filename)) //Concatenate paths console.log(path.join(__dirname,'test','hello.html'))
fs
const fs = require("fs");
const path = require("path");
//for creating folder
// path, options,callback
fs.mkdir(path.join(__dirname, "/test"), {}, (err) => {
if (err) {
throw err;
}
console.log("Folder created");
});
//for creating file
// path, options,callback
fs.writeFile(
path.join(__dirname, "/test", "hello.txt"),
"Hello World",
(err) => {
if (err) {
throw err;
}
console.log("Folder Written...");
fs.appendFile(
path.join(__dirname, "/test", "hello.txt"),
" I love node js",
(err) => {
if (err) {
throw err;
}
console.log("Folder Written...");
}
);
}
);
//Read File
fs.readFile(path.join(__dirname,'/test','hello.txt'),'utf-8',(err,data)=>{
if (err) {
throw err;
}
console.log(data);
})
//Rename File
fs.rename(
path.join(__dirname,'/test','hello.txt'),
path.join(__dirname,'/test','helloWorld.txt'),
err =>{
if (err) {
throw err;
}
console.log("File renamed...")
}
)
os
const os = require("os")
//platform
console.log(os.platform())
//architecture
console.log(os.arch())
//CPU core info
console.log(os.cpus())
//free memory
console.log(os.freemem())
//total memory
console.log(os.totalmem());
//home dir
console.log(os.homedir())
//up time
console.log(os.uptime())
URL
const url = require("url");
const myUrl = new URL("http://mywebsite.com/hello.html?id=100&status=active")
//Serialized URL
console.log(myUrl.href)
//Host root domain
console.log(myUrl.host)
//Hostname does not get host
console.log(myUrl.hostname)
//path name
console.log(myUrl.pathname)
//Serialized query
console.log(myUrl.search)
//Params object
myUrl.searchParams.append('abc','123')
console.log(myUrl.search3Params)
HTTP
const http = require("http");
http.createServer((req,res)=>{
res.write("Hello World");
res.end();
}).listen(5000,()=>console.log("Server is running"));
Emitters in Node JS
const EventEmitter = require('events');
// Create a custom event emitter for the notification system
class NotificationSystem extends EventEmitter {}
// Instantiate the custom event emitter
const notificationEmitter = new NotificationSystem();
// Function to send a notification to a customer
function sendNotification(customer, product) {
console.log(`Notifying ${customer} that ${product} is back in stock.`);
}
// Register a custom event for product availability
notificationEmitter.on('productAvailable', (customer, product) => {
sendNotification(customer, product);
});
// Simulate a product coming back in stock
const product = 'Example Product';
const interestedCustomers = ['Customer1', 'Customer2', 'Customer3'];
for (const customer of interestedCustomers) {
// Emit the 'productAvailable' event for each interested customer
notificationEmitter.emit('productAvailable', customer, product);
}
Creating a Server completely using Node JS
const http = require("http");
const path = require("path");
const fs = require("fs");
const server = http.createServer((req, res) => {
// Handle the root URL ("/")
if (req.url === "/") {
fs.readFile(
path.join(__dirname, "public", "index.html"),
(err, content) => {
if (err) {
throw err;
}
res.writeHead(200, { "Content-Type": "text/html" });
res.end(content);
}
);
} else if (req.url === "/about") {
fs.readFile(
path.join(__dirname, "public", "about.html"),
(err, content) => {
if (err) {
throw err;
}
res.writeHead(200, { "Content-Type": "text/html" });
res.end(content);
}
)
} else if (req.url === "/api/users") {
const users = [
{ name: "Avez", age: 20 },
{ name: "John", age: 50 },
];
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(users));
} else {
// Serve static files (JavaScript, CSS, images)
const filePath = path.join(__dirname, "public", req.url);
const extname = path.extname(filePath);
// Set the content type based on the file extension
let contentType = "text/html";
switch (extname) {
case ".js":
contentType = "text/javascript";
break;
case ".css":
contentType = "text/css";
break;
case ".jpg":
contentType = "image/jpeg";
break;
case ".png":
contentType = "image/png";
break;
}
fs.readFile(filePath, (err, content) => {
if (err) {
if (err.code === "ENOENT") {
// Page not found
fs.readFile(
path.join(__dirname, "public", "404.html"),
(err, content) => {
res.writeHead(404, { "Content-Type": "text/html" });
res.end(content, "utf8");
}
);
} else {
// Server error
res.writeHead(500);
res.end(`Server Error: ${err.code}`);
}
} else {
// Serve the file
res.writeHead(200, { "Content-Type": contentType });
res.end(content);
}
});
}
});
const PORT = 5000;
server.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
What is package.json
The package.json file in Node JS is the heart of the entire application, This file holds the metadata for a particular project
What is a callback hell?
Callback hell, also known as the Pyramid of Doom, refers to a situation in JavaScript and Node.js where code becomes deeply nested and difficult to read and maintain due to the excessive use of callbacks, especially in asynchronous operations. It typically occurs when you have multiple asynchronous tasks that depend on the results of previous tasks, leading to a chain of nested callbacks. The code structure ends up looking like a pyramid or a series of nested blocks.
Explain the concept of middleware
Middleware is a function that receives the request and response objects. Most task that middleware function perform are
Executing any code, update or modify the request and response object
Finish the request-response cycle
Invoke the next middleware in the stack
const express = require('express');
const app = express();
const port = 3000;
// Define a custom middleware function
const requestLogger = (req, res, next) => {
// Log information about the incoming request
console.log(`[${new Date().toLocaleString()}] ${req.method} request to ${req.url}`);
// Continue to the next middleware or route handler
next();
};
// Use the custom middleware for all routes
app.use(requestLogger);
// Define a simple route
app.get('/', (req, res) => {
res.send('Hello, Express!');
});
// Start the Express server
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});
When you run this code, the requestLogger
middleware will log details of every incoming HTTP request to the console, providing a simple example of how middleware can intercept and process requests in an Express.js application.
if you want to achieve similar functionality without used middleware then we have to handle request logging and routing directly with our route handlers
const express = require('express');
const app = express();
const port = 3000;
// Define a route for the root path ("/")
app.get('/', (req, res) => {
// Log information about the incoming request
console.log(`[${new Date().toLocaleString()}] ${req.method} request to ${req.url}`);
// Respond with a message
res.send('Hello, Express!');
});
// Define a route for the "/about" path
app.get('/about', (req, res) => {
// Log information about the incoming request
console.log(`[${new Date().toLocaleString()}] ${req.method} request to ${req.url}`);
// Respond with a message
res.send('About Us');
});
// Define a route for the "/contact" path
app.get('/contact', (req, res) => {
// Log information about the incoming request
console.log(`[${new Date().toLocaleString()}] ${req.method} request to ${req.url}`);
// Respond with a message
res.send('Contact Us');
});
// Start the Express server
app.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});
What is REPL
Read: Read the user input
Evaluate: Receives and evaluates the input
Print: Print the final result
Loop: Loop the provided command until CTRL + C is pressed twice
What are streams in Node JS
Streams are objects that enable you to read data or write data continuously
There are four types of Streams
Readable Streams:
- Readable streams are used for reading data from a source. Common sources include files, HTTP requests, and data generated in memory.
Writable Streams:
- Writable streams are used for writing data to a destination. Common destinations include files, network sockets, or HTTP responses.
Duplex Streams:
- Duplex streams are both readable and writable. They are often used for communication, where data can be both sent and received simultaneously.
Transform Streams:
- Transform streams are a subset of duplex streams that allow for data transformation during the read or write process. They are often used to modify data as it flows from a source to a destination.
What are two types of API functions in Node JS
Synchronous (Blocking) API Functions:
Synchronous API functions block the execution of your code until the operation is completed. They wait for the operation to finish and return the result immediately.
const fs = require('fs'); const data = fs.readFileSync('example.txt', 'utf8'); console.log(data);
Asynchronous (Non-Blocking) API Functions:
Asynchronous API functions do not block the execution of your code. Instead, they initiate the operation and immediately return control to your code, allowing it to continue executing other tasks.
const fs = require('fs');
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
} else {
console.log(data);
}
});
What is libuv
libuv is a core component of Node.js that provides an event loop and platform-independent abstractions for handling asynchronous I/O operations. It allows Node.js to efficiently manage tasks like reading files, making network requests, and handling timers
What is the purpose of NODE_ENV
NODE_ENV is an environment variable used in Node.js to determine the runtime environment of an application. It helps developers and applications to adapt behavior based on whether they are running in a development, production, or other environment.
Can DOM be accessed in Node JS?
DOM cannot be accessed in node js . DOM is a browser-specific API that allows for the manipulation of HTML or XML documents, Since Node JS does not run in a browser it does not have access to DOM
What is ESlint?
ESLint stands for ECMAScript Lint. The name reflects its role as a tool for linting (analyzing and identifying issues in) ECMAScript or JavaScript code.
What is a Passport in Node JS?
Passport is a popular authentication middleware for Node JS, Passport supports many authentication mechanisms, including username/password,social logging like Facebook, Google and JWT
Does Node JS provide any debugger?
Yes Node JS provides a built-in debugger called Node JS inspector and is accessed using inspect
or inspect-brk
flags when you use Node JS application
Is Cryptography supported in Node JS?
Yes Node JS provides built-in support for cryptography through the crypto module
Why does Google use the V8 engine for Node JS?
Google uses the V8 engine. It is Chrome runtime engine that converts Javascript code into native machine code, Its speeds up the application execution and response process and gives you a fast running applications