Skip to content

Commit 1b5a6e9

Browse files
authored
Merge pull request #12 from Satyasn01/feature/nodejs-notes-added
Feature/nodejs notes added
2 parents cd99d27 + e1ed251 commit 1b5a6e9

14 files changed

+972
-27
lines changed

NodeJS/architecture.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Node.js Architecture
2+
3+
## Overview
4+
Node.js is designed to build scalable network applications and execute JavaScript code on the server side. At the heart of Node.js lies its non-blocking, event-driven architecture that enables high throughput and scalability in web applications with many I/O operations.
5+
6+
## Event-Driven Architecture
7+
Node.js operates on a single-thread model with event looping. This model is quite different from traditional multi-threaded server architectures. In traditional architectures, each client request spawns a new thread or process to handle the request and make further blocking calls to perform operations. This approach is resource-intensive and can be inefficient for high traffic applications due to the overhead of context switching and the memory usage associated with each thread.
8+
9+
### The Event Loop
10+
The event loop is what allows Node.js to perform non-blocking I/O operations, despite the fact that JavaScript is single-threaded. The loop is essentially a loop that continuously checks for events and dispatches them to be handled by any awaiting callbacks.
11+
12+
#### Process:
13+
1. **Events**: Events are actions generated as a result of an external interaction with the system (like web requests, file I/O, network operations).
14+
2. **Event Queue**: Events are queued in the event queue when the system receives them.
15+
3. **Event Loop**: The event loop continuously checks the event queue and processes the events by invoking the associated callback functions.
16+
4. **Callback Functions**: These are functions specified to be executed in response to events.
17+
18+
## Non-blocking I/O
19+
In Node.js, when a request is made (for example, a file read), the request is sent to the system kernel. Most modern operating systems are capable of performing non-blocking I/O operations, which allows Node.js to offload I/O operations, freeing the event loop to handle other operations in the meantime. This ability to handle a large number of simultaneous connections with a single server instance is a key feature of Node.js.
20+
21+
### Benefits:
22+
- **Efficiency**: The non-blocking nature means the server can handle more requests with fewer resources.
23+
- **Scalability**: It's easier to scale applications horizontally and vertically.
24+
- **Simplicity**: Writing server code is easier and more intuitive, following an event-driven approach.
25+
26+
## Use of Threads
27+
Despite being single-threaded at the application layer, Node.js uses multiple threads in the background. This is managed by libuv, the library that underlies Node.js and handles asynchronous I/O operations. libuv uses a fixed-sized thread pool that handles the execution of operations that are too heavy for the event loop, such as file I/O or DNS lookups.
28+
29+
### libuv
30+
libuv is designed around the reactor pattern, which is a way of handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers.
31+
32+
## Conclusion
33+
Node.js's architecture is built to optimize throughput and scalability in web applications and is particularly effective for I/O-bound applications, data streaming applications, and JSON APIs for web clients. Understanding this architecture is crucial for developing efficient applications that can handle large volumes of data and traffic.
34+
35+
For deeper insights into Node.js internals, consider exploring the [Node.js official documentation](https://nodejs.org/en/docs/).

NodeJS/async_programming.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Asynchronous Programming in Node.js
2+
3+
## Overview
4+
Asynchronous programming is a fundamental aspect of Node.js, enabling it to perform non-blocking operations. This means that Node.js can continue to execute other code while waiting for slower operations like network requests or file reads to complete. This model is crucial for creating efficient and scalable applications.
5+
6+
## The Basics of Asynchronous Programming
7+
In Node.js, asynchronous programming is facilitated through callbacks, promises, and async/await syntax. Each method provides different levels of abstraction and usability improvements over the others.
8+
9+
### Callbacks
10+
Callbacks are functions passed into other functions as arguments and are executed after their parent function completes.
11+
12+
#### Example: Reading a File
13+
```javascript
14+
const fs = require('fs');
15+
16+
fs.readFile('/path/to/file', 'utf8', function(err, data) {
17+
if (err) {
18+
console.error("Error reading file:", err);
19+
return;
20+
}
21+
console.log("File content:", data);
22+
});
23+
```
24+
This example shows a non-blocking file read operation. The program can continue executing other code while the file is being read.
25+
26+
### Promises
27+
Promises are objects that represent the future result of an asynchronous operation. They can be in one of three states: fulfilled, rejected, or pending.
28+
29+
#### Example: Converting Callbacks to Promises
30+
```javascript
31+
const { readFile } = require('fs').promises;
32+
33+
readFile('/path/to/file', 'utf8')
34+
.then(data => console.log("File content:", data))
35+
.catch(err => console.error("Error reading file:", err));
36+
```
37+
This example uses the promise-based version of `readFile`. It provides a cleaner and more manageable approach to handling asynchronous results.
38+
39+
### Async/Await
40+
`async/await` syntax builds on promises, making asynchronous code look and behave a little more like synchronous code.
41+
42+
#### Example: Using Async/Await
43+
```javascript
44+
const { readFile } = require('fs').promises;
45+
46+
async function readMyFile() {
47+
try {
48+
const data = await readFile('/path/to/file', 'utf8');
49+
console.log("File content:", data);
50+
} catch (err) {
51+
console.error("Error reading file:", err);
52+
}
53+
}
54+
55+
readMyFile();
56+
```
57+
This example defines an async function that waits for the `readFile` promise to resolve before proceeding. This makes the code cleaner and easier to follow.
58+
59+
## Error Handling
60+
Error handling in asynchronous programming is crucial. Callbacks use conventional error-first callbacks, while promises and async/await use `catch` blocks or try/catch statements to handle errors.
61+
62+
## Conclusion
63+
Understanding asynchronous programming in Node.js is essential for building fast, responsive, and efficient applications. By mastering callbacks, promises, and async/await, developers can effectively manage complex data flows and operations without blocking the main execution thread.
64+
65+
For more details on asynchronous programming in Node.js, refer to the [Node.js Asynchronous Programming Guide](https://nodejs.org/en/docs/guides/).

NodeJS/best_practices.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Best Practices for Node.js Development
2+
3+
## Overview
4+
Adhering to best practices in Node.js development not only helps in maintaining code quality but also enhances application performance and security. This document outlines essential practices to follow when working with Node.js.
5+
6+
## 1. Keep Your Code Clean and Modular
7+
### Modularization
8+
Split your application into smaller, reusable modules that can be managed and updated independently. This approach not only makes the code easier to understand but also simplifies testing and maintenance.
9+
10+
#### Example: Using Modules
11+
```javascript
12+
// greeting.js
13+
module.exports = function greet(name) {
14+
console.log(`Hello, ${name}!`);
15+
};
16+
17+
// app.js
18+
const greet = require('./greeting');
19+
greet('World');
20+
```
21+
22+
## 2. Handle Errors Properly
23+
### Asynchronous Error Handling
24+
Use `try...catch` with async/await for effective error handling. Ensure that all possible failures are handled gracefully to prevent the application from crashing.
25+
26+
#### Example: Error Handling in Async Functions
27+
```javascript
28+
async function fetchData(url) {
29+
try {
30+
const response = await fetch(url);
31+
const data = await response.json();
32+
return data;
33+
} catch (error) {
34+
console.error("Error fetching data:", error);
35+
}
36+
}
37+
```
38+
39+
## 3. Use Environment Variables
40+
### Security and Configuration
41+
Store configuration options and sensitive information in environment variables instead of hard-coding them into your application's source code.
42+
43+
#### Example: Using Environment Variables
44+
```javascript
45+
const databaseConfig = {
46+
host: process.env.DB_HOST,
47+
user: process.env.DB_USER,
48+
password: process.env.DB_PASSWORD,
49+
database: process.env.DB_NAME
50+
};
51+
```
52+
53+
## 4. Implement Logging
54+
### Monitoring and Debugging
55+
Use a robust logging framework like Winston or Morgan to log application data. This helps in monitoring application behavior and troubleshooting issues in production.
56+
57+
#### Example: Simple Logging with Morgan
58+
```javascript
59+
const express = require('express');
60+
const morgan = require('morgan');
61+
62+
const app = express();
63+
app.use(morgan('tiny'));
64+
65+
app.get('/', (req, res) => {
66+
res.send('Hello World!');
67+
});
68+
69+
app.listen(3000, () => console.log('Server is running on port 3000'));
70+
```
71+
72+
## 5. Optimize Performance
73+
### Use of Caching
74+
Implement caching strategies where appropriate to reduce database load and improve response times. Tools like Redis can be highly effective for caching data.
75+
76+
#### Example: Simple Redis Caching
77+
```javascript
78+
const redis = require('redis');
79+
const client = redis.createClient();
80+
81+
client.on('error', (err) => console.log('Redis Client Error', err));
82+
83+
async function cacheMiddleware(req, res, next) {
84+
const { id } = req.params;
85+
const data = await client.get(id);
86+
87+
if (data != null) {
88+
res.send(data);
89+
} else {
90+
next();
91+
}
92+
}
93+
```
94+
95+
## 6. Use Proper Asynchronous Programming Practices
96+
### Avoid Callback Hell
97+
Prefer promises and async/await over nested callbacks to keep your code clean and readable.
98+
99+
## 7. Perform Regular Security Audits
100+
### Keep Dependencies Updated
101+
Regularly update your project dependencies to mitigate vulnerabilities. Tools like npm audit can automate this process.
102+
103+
## Conclusion
104+
Following these best practices will help you build robust, efficient, and secure Node.js applications. Continuously refine and update your practices as the technology and standards evolve.
105+
106+
For more comprehensive guidelines and latest updates in best practices, refer to the official [Node.js documentation](https://nodejs.org/).

NodeJS/core_modules.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Core Modules in Node.js
2+
3+
## Overview
4+
Node.js comes with a rich library of various core modules which are compiled into the binary distribution and load automatically when Node.js processes start. These modules provide foundational functionalities necessary for building scalable applications.
5+
6+
## 1. HTTP Module
7+
The HTTP module is one of the key modules for creating web servers and handling HTTP requests and responses.
8+
9+
### Creating a Simple Web Server
10+
```javascript
11+
const http = require('http');
12+
13+
const server = http.createServer((req, res) => {
14+
res.statusCode = 200;
15+
res.setHeader('Content-Type', 'text/plain');
16+
res.end('Hello World\n');
17+
});
18+
19+
server.listen(3000, '127.0.0.1', () => {
20+
console.log('Server running at http://127.0.0.1:3000/');
21+
});
22+
```
23+
This example demonstrates how to create a basic web server that listens on port 3000.
24+
25+
## 2. File System Module (fs)
26+
The File System module allows you to work with the file system on your computer.
27+
28+
### Reading a File Asynchronously
29+
```javascript
30+
const fs = require('fs');
31+
32+
fs.readFile('example.txt', 'utf8', (err, data) => {
33+
if (err) {
34+
console.error(err);
35+
return;
36+
}
37+
console.log(data);
38+
});
39+
```
40+
This function reads the contents of `example.txt` asynchronously, without blocking other operations.
41+
42+
## 3. Path Module
43+
The Path module provides utilities for working with file and directory paths.
44+
45+
### Example: Formatting Paths
46+
```javascript
47+
const path = require('path');
48+
49+
const filePath = path.join('/users/joe', 'test.txt');
50+
console.log(filePath);
51+
```
52+
This code snippet demonstrates how to use the `path.join` method to create a consistent file path across different operating systems.
53+
54+
## 4. Events Module
55+
Node.js is built around an event-driven architecture, primarily using the EventEmitter class, which is part of the Events module.
56+
57+
### Example: Emitting and Handling Events
58+
```javascript
59+
const EventEmitter = require('events');
60+
class MyEmitter extends EventEmitter {}
61+
62+
const myEmitter = new MyEmitter();
63+
myEmitter.on('event', () => {
64+
console.log('an event occurred!');
65+
});
66+
myEmitter.emit('event');
67+
```
68+
This example shows how to create an event emitter instance, listen for an "event", and trigger the event.
69+
70+
## Conclusion
71+
These core modules form the backbone of many Node.js applications, providing essential functionalities that are needed for developing robust server-side logic. Understanding and utilizing these modules effectively can greatly enhance your application's performance and scalability.
72+
73+
For more detailed information and additional functionalities of each core module, refer to the official [Node.js API documentation](https://nodejs.org/api/).

NodeJS/deployment.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Deployment of Node.js Applications
2+
3+
## Overview
4+
Deploying a Node.js application involves several steps to ensure that the application runs smoothly in a production environment. This guide covers essential deployment practices, focusing on using PM2 for process management and Docker for containerization.
5+
6+
## 1. Using PM2
7+
PM2 is a popular process manager for Node.js applications that provides features like automatic restarts, load balancing, and monitoring.
8+
9+
### Installing PM2
10+
```bash
11+
npm install pm2 -g
12+
```
13+
14+
### Starting an Application with PM2
15+
```bash
16+
pm2 start app.js --name my-app
17+
```
18+
This command starts your Node.js application with PM2, which will automatically restart it if the application crashes.
19+
20+
### Monitoring Your Application
21+
```bash
22+
pm2 status
23+
pm2 monit
24+
```
25+
These commands display the status of your application and provide a dashboard for monitoring runtime metrics.
26+
27+
## 2. Containerization with Docker
28+
Docker provides a standardized environment for your application, ensuring it works uniformly across different development and staging environments.
29+
30+
### Creating a Dockerfile
31+
Create a `Dockerfile` in your Node.js application directory:
32+
```Dockerfile
33+
# Use the official Node.js 14 image.
34+
# https://hub.docker.com/_/node
35+
FROM node:14
36+
37+
# Create and change to the app directory.
38+
WORKDIR /usr/src/app
39+
40+
# Copy application dependency manifests to the container image.
41+
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
42+
# Copying this separately prevents re-running npm install on every code change.
43+
COPY package*.json ./
44+
45+
# Install production dependencies.
46+
RUN npm install --only=production
47+
48+
# Copy local code to the container image.
49+
COPY . .
50+
51+
# Bind the port that the image will run on
52+
EXPOSE 8080
53+
54+
# Run the web service on container startup.
55+
CMD [ "node", "app.js" ]
56+
```
57+
58+
### Building and Running the Docker Image
59+
```bash
60+
docker build -t my-node-app .
61+
docker run -p 8080:8080 my-node-app
62+
```
63+
This will build your Docker image and run it, exposing the application on port 8080.
64+
65+
## 3. Best Practices for Deployment
66+
- **Environment Variables**: Use environment variables to manage configuration and secrets, avoiding hard-coded values.
67+
- **Logging**: Implement comprehensive logging to help diagnose issues after deployment. Consider a cloud-based logging solution for scalability.
68+
- **Security**: Ensure that your Node.js environment is up to date with the latest security patches. Use tools like `npm audit` to detect and resolve vulnerabilities.
69+
70+
## Conclusion
71+
Deploying Node.js applications can vary based on the environment and specific requirements of the project. Using tools like PM2 and Docker can greatly simplify the process and increase the robustness of your application. Always ensure to test your deployment process thoroughly in a staging environment before going live.
72+
73+
For more detailed guidelines on deploying Node.js applications, refer to the [official Node.js deployment guide](https://nodejs.org/en/docs/guides/).

0 commit comments

Comments
 (0)