In this section, we will learn how to serve static files using Node.js. Static files include HTML, CSS, JavaScript, images, and other resources that do not change dynamically. Serving static files is a common requirement for web applications, and Node.js provides several ways to achieve this.
Key Concepts
- Static Files: Files that do not change dynamically and are served as-is to the client.
- HTTP Server: A server that listens for HTTP requests and serves responses.
- File System Module: A Node.js module that allows interaction with the file system.
- Path Module: A Node.js module that provides utilities for working with file and directory paths.
Steps to Serve Static Files
- Set Up a Basic HTTP Server: Create a simple HTTP server using the
http
module. - Read Static Files: Use the
fs
module to read static files from the file system. - Serve Static Files: Send the static files as responses to HTTP requests.
Example: Serving Static Files
Step 1: Set Up a Basic HTTP Server
First, let's create a basic HTTP server that listens for incoming requests.
const http = require('http'); const fs = require('fs'); const path = require('path'); const server = http.createServer((req, res) => { // Handle requests here }); const PORT = 3000; server.listen(PORT, () => { console.log(`Server is listening on port ${PORT}`); });
Step 2: Read Static Files
Next, we will read static files from the file system. For this example, let's assume we have an index.html
file in a public
directory.
<!-- 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>Static File Example</title> </head> <body> <h1>Hello, World!</h1> </body> </html>
Step 3: Serve Static Files
We will modify our server to serve the index.html
file when the root URL (/
) is requested.
const http = require('http'); const fs = require('fs'); const path = require('path'); const server = http.createServer((req, res) => { if (req.url === '/') { const filePath = path.join(__dirname, 'public', 'index.html'); fs.readFile(filePath, (err, content) => { if (err) { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Internal Server Error'); } else { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(content); } }); } else { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Not Found'); } }); const PORT = 3000; server.listen(PORT, () => { console.log(`Server is listening on port ${PORT}`); });
Handling Different File Types
To serve different types of static files (e.g., CSS, JavaScript, images), we need to determine the content type based on the file extension.
const mimeTypes = { '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript', '.png': 'image/png', '.jpg': 'image/jpeg', '.gif': 'image/gif' }; const server = http.createServer((req, res) => { let filePath = path.join(__dirname, 'public', req.url === '/' ? 'index.html' : req.url); const extname = String(path.extname(filePath)).toLowerCase(); const contentType = mimeTypes[extname] || 'application/octet-stream'; fs.readFile(filePath, (err, content) => { if (err) { if (err.code === 'ENOENT') { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Not Found'); } else { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Internal Server Error'); } } else { res.writeHead(200, { 'Content-Type': contentType }); res.end(content); } }); }); const PORT = 3000; server.listen(PORT, () => { console.log(`Server is listening on port ${PORT}`); });
Practical Exercise
Exercise: Serve Static Files
- Create a directory named
public
in your project root. - Add an
index.html
file, astyle.css
file, and ascript.js
file to thepublic
directory. - Modify the server code to serve these files based on the request URL.
Solution
// 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>Static File Example</title> <link rel="stylesheet" href="style.css"> </head> <body> <h1>Hello, World!</h1> <script src="script.js"></script> </body> </html> // public/style.css body { background-color: #f0f0f0; font-family: Arial, sans-serif; } // public/script.js console.log('Hello from script.js'); // server.js const http = require('http'); const fs = require('fs'); const path = require('path'); const mimeTypes = { '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript', '.png': 'image/png', '.jpg': 'image/jpeg', '.gif': 'image/gif' }; const server = http.createServer((req, res) => { let filePath = path.join(__dirname, 'public', req.url === '/' ? 'index.html' : req.url); const extname = String(path.extname(filePath)).toLowerCase(); const contentType = mimeTypes[extname] || 'application/octet-stream'; fs.readFile(filePath, (err, content) => { if (err) { if (err.code === 'ENOENT') { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Not Found'); } else { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('Internal Server Error'); } } else { res.writeHead(200, { 'Content-Type': contentType }); res.end(content); } }); }); const PORT = 3000; server.listen(PORT, () => { console.log(`Server is listening on port ${PORT}`); });
Summary
In this section, we learned how to serve static files using Node.js. We covered the following key points:
- Setting up a basic HTTP server.
- Reading static files from the file system.
- Serving static files based on the request URL.
- Handling different file types using MIME types.
By understanding these concepts, you can now serve static files in your Node.js applications, providing essential resources like HTML, CSS, and JavaScript to your users.
Node.js Course
Module 1: Introduction to Node.js
Module 2: Core Concepts
Module 3: File System and I/O
Module 4: HTTP and Web Servers
Module 5: NPM and Package Management
- Introduction to NPM
- Installing and Using Packages
- Creating and Publishing Packages
- Semantic Versioning
Module 6: Express.js Framework
- Introduction to Express.js
- Setting Up an Express Application
- Middleware
- Routing in Express
- Error Handling
Module 7: Databases and ORMs
- Introduction to Databases
- Using MongoDB with Mongoose
- Using SQL Databases with Sequelize
- CRUD Operations
Module 8: Authentication and Authorization
Module 9: Testing and Debugging
- Introduction to Testing
- Unit Testing with Mocha and Chai
- Integration Testing
- Debugging Node.js Applications
Module 10: Advanced Topics
Module 11: Deployment and DevOps
- Environment Variables
- Using PM2 for Process Management
- Deploying to Heroku
- Continuous Integration and Deployment