Node.js Core
Node.js Core
Section titled “Node.js Core”Node.js brings JavaScript to the server, enabling full-stack development with a single language. This comprehensive guide covers Node.js fundamentals, core modules, and advanced server-side development patterns.
Getting Started with Node.js
Section titled “Getting Started with Node.js”Installation and Setup
Section titled “Installation and Setup”# Install Node.js using Node Version Manager (recommended)curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bashnvm install --ltsnvm use --lts
# Verify installationnode --versionnpm --version
# Initialize a new Node.js projectmkdir my-node-appcd my-node-appnpm init -y
# Install dependenciesnpm install express lodashnpm install --save-dev nodemon jest
Basic Node.js Application
Section titled “Basic Node.js Application”// app.js - Simple HTTP serverconst http = require('http');const url = require('url');const querystring = require('querystring');
const server = http.createServer((req, res) => { const parsedUrl = url.parse(req.url); const path = parsedUrl.pathname; const query = querystring.parse(parsedUrl.query);
// Set CORS headers res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
// Simple routing if (path === '/') { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ message: 'Welcome to Node.js Server', timestamp: new Date().toISOString() })); } else if (path === '/api/users' && req.method === 'GET') { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify([ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' } ])); } else { res.writeHead(404, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Not Found' })); }});
const PORT = process.env.PORT || 3000;server.listen(PORT, () => { console.log(`Server running on port ${PORT}`);});
// Graceful shutdownprocess.on('SIGTERM', () => { console.log('SIGTERM received, shutting down gracefully'); server.close(() => { process.exit(0); });});
Core Modules
Section titled “Core Modules”File System (fs)
Section titled “File System (fs)”const fs = require('fs').promises;const path = require('path');
class FileManager { static async readFile(filePath) { try { const data = await fs.readFile(filePath, 'utf8'); return data; } catch (error) { throw new Error(`Failed to read file ${filePath}: ${error.message}`); } }
static async writeFile(filePath, data) { try { await fs.writeFile(filePath, data, 'utf8'); console.log(`File written successfully: ${filePath}`); } catch (error) { throw new Error(`Failed to write file ${filePath}: ${error.message}`); } }
static async appendFile(filePath, data) { try { await fs.appendFile(filePath, data, 'utf8'); } catch (error) { throw new Error(`Failed to append to file ${filePath}: ${error.message}`); } }
static async deleteFile(filePath) { try { await fs.unlink(filePath); console.log(`File deleted: ${filePath}`); } catch (error) { throw new Error(`Failed to delete file ${filePath}: ${error.message}`); } }
static async createDirectory(dirPath) { try { await fs.mkdir(dirPath, { recursive: true }); console.log(`Directory created: ${dirPath}`); } catch (error) { throw new Error(`Failed to create directory ${dirPath}: ${error.message}`); } }
static async listDirectory(dirPath) { try { const files = await fs.readdir(dirPath); const fileStats = await Promise.all( files.map(async (file) => { const filePath = path.join(dirPath, file); const stats = await fs.stat(filePath); return { name: file, path: filePath, isDirectory: stats.isDirectory(), size: stats.size, modified: stats.mtime }; }) ); return fileStats; } catch (error) { throw new Error(`Failed to list directory ${dirPath}: ${error.message}`); } }
static async copyFile(source, destination) { try { await fs.copyFile(source, destination); console.log(`File copied from ${source} to ${destination}`); } catch (error) { throw new Error(`Failed to copy file: ${error.message}`); } }
static async watchFile(filePath, callback) { try { const watcher = fs.watch(filePath, (eventType, filename) => { callback(eventType, filename); }); return watcher; } catch (error) { throw new Error(`Failed to watch file ${filePath}: ${error.message}`); } }}
// Usage examplesasync function fileOperations() { try { // Create directory await FileManager.createDirectory('./data');
// Write file await FileManager.writeFile('./data/users.json', JSON.stringify([ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ], null, 2));
// Read file const users = await FileManager.readFile('./data/users.json'); console.log('Users:', JSON.parse(users));
// List directory const files = await FileManager.listDirectory('./data'); console.log('Files in directory:', files);
// Watch file for changes const watcher = await FileManager.watchFile('./data/users.json', (eventType, filename) => { console.log(`File ${filename} was ${eventType}`); });
// Clean up watcher after 10 seconds setTimeout(() => watcher.close(), 10000);
} catch (error) { console.error('File operation failed:', error.message); }}
HTTP and HTTPS
Section titled “HTTP and HTTPS”const http = require('http');const https = require('https');const fs = require('fs');const url = require('url');
class HTTPServer { constructor(options = {}) { this.port = options.port || 3000; this.hostname = options.hostname || 'localhost'; this.routes = new Map(); this.middleware = []; this.server = null; }
use(middleware) { this.middleware.push(middleware); }
route(method, path, handler) { const key = `${method.toUpperCase()}:${path}`; this.routes.set(key, handler); }
get(path, handler) { this.route('GET', path, handler); }
post(path, handler) { this.route('POST', path, handler); }
put(path, handler) { this.route('PUT', path, handler); }
delete(path, handler) { this.route('DELETE', path, handler); }
async handleRequest(req, res) { const parsedUrl = url.parse(req.url, true); const path = parsedUrl.pathname; const method = req.method; const key = `${method}:${path}`;
// Enhanced request object req.query = parsedUrl.query; req.params = {};
// Parse request body for POST/PUT requests if (method === 'POST' || method === 'PUT') { req.body = await this.parseBody(req); }
// Enhanced response object res.json = (data) => { res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(data)); };
res.status = (code) => { res.statusCode = code; return res; };
// Execute middleware for (const middleware of this.middleware) { try { await middleware(req, res); } catch (error) { res.status(500).json({ error: 'Middleware error', message: error.message }); return; } }
// Route handling const handler = this.routes.get(key); if (handler) { try { await handler(req, res); } catch (error) { res.status(500).json({ error: 'Internal server error', message: error.message }); } } else { res.status(404).json({ error: 'Not Found' }); } }
async parseBody(req) { return new Promise((resolve, reject) => { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { try { resolve(body ? JSON.parse(body) : {}); } catch (error) { reject(error); } }); req.on('error', reject); }); }
start() { this.server = http.createServer((req, res) => { this.handleRequest(req, res); });
this.server.listen(this.port, this.hostname, () => { console.log(`Server running at http://${this.hostname}:${this.port}/`); });
return this.server; }
stop() { if (this.server) { this.server.close(); } }}
// HTTPS Serverclass HTTPSServer extends HTTPServer { constructor(options = {}) { super(options); this.sslOptions = options.ssl || {}; }
start() { if (!this.sslOptions.key || !this.sslOptions.cert) { throw new Error('SSL key and certificate are required for HTTPS server'); }
this.server = https.createServer(this.sslOptions, (req, res) => { this.handleRequest(req, res); });
this.server.listen(this.port, this.hostname, () => { console.log(`HTTPS Server running at https://${this.hostname}:${this.port}/`); });
return this.server; }}
// Middleware examplesconst loggingMiddleware = (req, res) => { console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);};
const corsMiddleware = (req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');};
const authMiddleware = (req, res) => { const token = req.headers.authorization; if (!token) { res.status(401).json({ error: 'Authorization token required' }); return; } // Verify token logic here req.user = { id: 1, name: 'Authenticated User' };};
// Usageconst server = new HTTPServer({ port: 3000 });
server.use(loggingMiddleware);server.use(corsMiddleware);
server.get('/', (req, res) => { res.json({ message: 'Welcome to Node.js API' });});
server.get('/api/users', authMiddleware, (req, res) => { res.json([ { id: 1, name: 'Alice', email: 'alice@example.com' }, { id: 2, name: 'Bob', email: 'bob@example.com' } ]);});
server.post('/api/users', authMiddleware, (req, res) => { const newUser = { id: Date.now(), ...req.body, createdAt: new Date().toISOString() }; res.status(201).json(newUser);});
server.start();
Streams
Section titled “Streams”const { Readable, Writable, Transform, pipeline } = require('stream');const fs = require('fs');const zlib = require('zlib');
// Custom Readable Streamclass NumberStream extends Readable { constructor(options = {}) { super(options); this.current = options.start || 1; this.max = options.max || 100; }
_read() { if (this.current <= this.max) { this.push(`${this.current}\n`); this.current++; } else { this.push(null); // End of stream } }}
// Custom Writable Streamclass FileWriterStream extends Writable { constructor(filename, options = {}) { super(options); this.filename = filename; this.fd = null; }
_construct(callback) { fs.open(this.filename, 'w', (err, fd) => { if (err) { callback(err); } else { this.fd = fd; callback(); } }); }
_write(chunk, encoding, callback) { fs.write(this.fd, chunk, callback); }
_destroy(err, callback) { if (this.fd) { fs.close(this.fd, (closeErr) => callback(closeErr || err)); } else { callback(err); } }}
// Custom Transform Streamclass UpperCaseTransform extends Transform { _transform(chunk, encoding, callback) { this.push(chunk.toString().toUpperCase()); callback(); }}
class JSONParseTransform extends Transform { constructor(options = {}) { super({ ...options, objectMode: true }); this.buffer = ''; }
_transform(chunk, encoding, callback) { this.buffer += chunk.toString(); const lines = this.buffer.split('\n'); this.buffer = lines.pop(); // Keep incomplete line in buffer
for (const line of lines) { if (line.trim()) { try { const obj = JSON.parse(line); this.push(obj); } catch (error) { this.emit('error', error); return; } } } callback(); }
_flush(callback) { if (this.buffer.trim()) { try { const obj = JSON.parse(this.buffer); this.push(obj); } catch (error) { this.emit('error', error); return; } } callback(); }}
// Stream utilitiesclass StreamUtils { static async streamToString(stream) { const chunks = []; return new Promise((resolve, reject) => { stream.on('data', chunk => chunks.push(chunk)); stream.on('error', reject); stream.on('end', () => resolve(Buffer.concat(chunks).toString())); }); }
static async streamToBuffer(stream) { const chunks = []; return new Promise((resolve, reject) => { stream.on('data', chunk => chunks.push(chunk)); stream.on('error', reject); stream.on('end', () => resolve(Buffer.concat(chunks))); }); }
static createBackpressureAwareStream(processingFunction) { return new Transform({ objectMode: true, async transform(chunk, encoding, callback) { try { const result = await processingFunction(chunk); callback(null, result); } catch (error) { callback(error); } } }); }}
// File processing with streamsasync function processLargeFile() { const readStream = fs.createReadStream('./large-file.txt'); const writeStream = fs.createWriteStream('./processed-file.txt'); const gzipStream = zlib.createGzip(); const upperCaseStream = new UpperCaseTransform();
// Using pipeline for better error handling pipeline( readStream, upperCaseStream, gzipStream, writeStream, (error) => { if (error) { console.error('Pipeline failed:', error); } else { console.log('Pipeline succeeded'); } } );}
// Memory-efficient CSV processingclass CSVProcessor { static createParser() { return new Transform({ objectMode: true, transform(chunk, encoding, callback) { const lines = chunk.toString().split('\n');
for (const line of lines) { if (line.trim()) { const columns = line.split(',').map(col => col.trim()); this.push(columns); } } callback(); } }); }
static createFilter(filterFunction) { return new Transform({ objectMode: true, transform(chunk, encoding, callback) { if (filterFunction(chunk)) { this.push(chunk); } callback(); } }); }
static createMapper(mapFunction) { return new Transform({ objectMode: true, transform(chunk, encoding, callback) { try { const result = mapFunction(chunk); this.push(result); callback(); } catch (error) { callback(error); } } }); }}
Events and EventEmitter
Section titled “Events and EventEmitter”const EventEmitter = require('events');const { once, on } = require('events');
class CustomEventEmitter extends EventEmitter { constructor() { super(); this.maxListeners = 20; this.setMaxListeners(this.maxListeners); }
// Add typed event methods emitUserRegistered(user) { this.emit('user:registered', user); }
emitUserLoggedIn(user) { this.emit('user:logged-in', user); }
emitUserLoggedOut(userId) { this.emit('user:logged-out', userId); }
onUserRegistered(callback) { this.on('user:registered', callback); }
onUserLoggedIn(callback) { this.on('user:logged-in', callback); }
onUserLoggedOut(callback) { this.on('user:logged-out', callback); }}
// Application event busclass ApplicationEventBus extends EventEmitter { constructor() { super(); this.namespaces = new Map(); this.setupErrorHandling(); }
setupErrorHandling() { this.on('error', (error) => { console.error('EventBus Error:', error); });
// Handle uncaught exceptions in event handlers process.on('uncaughtException', (error) => { console.error('Uncaught Exception in Event Handler:', error); this.emit('error', error); }); }
// Namespaced events namespace(name) { if (!this.namespaces.has(name)) { this.namespaces.set(name, new EventEmitter()); } return this.namespaces.get(name); }
// Event with timeout emitWithTimeout(event, data, timeout = 5000) { return new Promise((resolve, reject) => { const timer = setTimeout(() => { reject(new Error(`Event ${event} timed out after ${timeout}ms`)); }, timeout);
this.once(`${event}:response`, (response) => { clearTimeout(timer); resolve(response); });
this.emit(event, data); }); }
// Async event handler support async emitAsync(event, ...args) { const listeners = this.listeners(event); const promises = listeners.map(listener => { try { const result = listener(...args); return Promise.resolve(result); } catch (error) { return Promise.reject(error); } });
return Promise.allSettled(promises); }
// Event metrics getEventMetrics() { const events = this.eventNames(); const metrics = {};
events.forEach(event => { metrics[event] = { listenerCount: this.listenerCount(event), maxListeners: this.getMaxListeners() }; });
return metrics; }}
// User service with eventsclass UserService extends EventEmitter { constructor() { super(); this.users = new Map(); this.setupEventHandlers(); }
setupEventHandlers() { this.on('user:registered', this.onUserRegistered.bind(this)); this.on('user:updated', this.onUserUpdated.bind(this)); this.on('user:deleted', this.onUserDeleted.bind(this)); }
async createUser(userData) { const user = { id: Date.now(), ...userData, createdAt: new Date(), updatedAt: new Date() };
this.users.set(user.id, user); this.emit('user:registered', user);
return user; }
async updateUser(id, updateData) { const user = this.users.get(id); if (!user) { throw new Error('User not found'); }
const updatedUser = { ...user, ...updateData, updatedAt: new Date() };
this.users.set(id, updatedUser); this.emit('user:updated', updatedUser, user);
return updatedUser; }
async deleteUser(id) { const user = this.users.get(id); if (!user) { throw new Error('User not found'); }
this.users.delete(id); this.emit('user:deleted', user);
return user; }
onUserRegistered(user) { console.log(`User registered: ${user.name} (${user.id})`); // Send welcome email, create profile, etc. }
onUserUpdated(updatedUser, previousUser) { console.log(`User updated: ${updatedUser.name} (${updatedUser.id})`); // Log changes, send notifications, etc. }
onUserDeleted(user) { console.log(`User deleted: ${user.name} (${user.id})`); // Cleanup related data, send notifications, etc. }}
// Event-driven architecture exampleclass OrderProcessingSystem extends EventEmitter { constructor() { super(); this.orders = new Map(); this.setupEventHandlers(); }
setupEventHandlers() { this.on('order:created', this.processPayment.bind(this)); this.on('payment:successful', this.fulfillOrder.bind(this)); this.on('payment:failed', this.handlePaymentFailure.bind(this)); this.on('order:fulfilled', this.sendConfirmation.bind(this)); this.on('order:cancelled', this.processRefund.bind(this)); }
async createOrder(orderData) { const order = { id: Date.now(), ...orderData, status: 'created', createdAt: new Date() };
this.orders.set(order.id, order); this.emit('order:created', order);
return order; }
async processPayment(order) { try { // Simulate payment processing await new Promise(resolve => setTimeout(resolve, 1000));
const success = Math.random() > 0.1; // 90% success rate
if (success) { order.status = 'paid'; order.paidAt = new Date(); this.emit('payment:successful', order); } else { order.status = 'payment_failed'; this.emit('payment:failed', order); } } catch (error) { order.status = 'payment_failed'; order.error = error.message; this.emit('payment:failed', order); } }
async fulfillOrder(order) { try { // Simulate order fulfillment await new Promise(resolve => setTimeout(resolve, 2000));
order.status = 'fulfilled'; order.fulfilledAt = new Date(); this.emit('order:fulfilled', order); } catch (error) { order.status = 'fulfillment_failed'; order.error = error.message; this.emit('fulfillment:failed', order); } }
handlePaymentFailure(order) { console.log(`Payment failed for order ${order.id}`); // Send notification to customer, retry payment, etc. }
sendConfirmation(order) { console.log(`Order ${order.id} fulfilled successfully`); // Send confirmation email, update inventory, etc. }
processRefund(order) { console.log(`Processing refund for order ${order.id}`); // Process refund, update accounting, etc. }}
// Usage examplesasync function eventExamples() { // Custom event emitter const customEmitter = new CustomEventEmitter();
customEmitter.onUserRegistered((user) => { console.log('User registered event:', user); });
customEmitter.emitUserRegistered({ id: 1, name: 'Alice' });
// Application event bus const eventBus = new ApplicationEventBus();
// User service const userService = new UserService(); const user = await userService.createUser({ name: 'Bob', email: 'bob@example.com' });
// Order processing system const orderSystem = new OrderProcessingSystem(); const order = await orderSystem.createOrder({ customerId: user.id, items: [{ id: 1, quantity: 2, price: 29.99 }], total: 59.98 });}
// Using events with async/awaitasync function waitForEvent() { const emitter = new EventEmitter();
// Emit event after delay setTimeout(() => { emitter.emit('data', { message: 'Hello World' }); }, 1000);
// Wait for single event const [data] = await once(emitter, 'data'); console.log('Received data:', data);
// Listen to multiple events emitter.emit('multiple', 1); emitter.emit('multiple', 2); emitter.emit('multiple', 3);
for await (const [value] of on(emitter, 'multiple')) { console.log('Multiple event value:', value); if (value === 3) break; }}
This comprehensive Node.js guide covers the fundamental concepts and core modules needed for server-side JavaScript development. Each section provides practical examples and best practices for building robust Node.js applications.
Continue exploring Node.js capabilities by diving into specific modules and building real-world applications.