Node.js 快速上手指南
Node.js 是基于 Chrome V8 引擎的 JavaScript 运行时,让 JS 脱离浏览器运行在服务端,支持异步 I/O、跨平台,是构建后端 API、CLI 工具、全栈应用的核心技术。本文涵盖 Node.js 核心语法、常用模块和实战示例,可直接复制代码运行。
一、快速安装与入门
- 安装 Node.js
Windows/Mac:下载官方安装包 nodejs.org(推荐 LTS 长期支持版);
Linux:
bash
运行Ubuntu/Debian
sudo apt update && sudo apt install nodejs npmCentOS/RHEL
sudo yum install nodejs npm
验证安装:
bash
运行
node -v # 查看Node版本(如v20.10.0)
npm -v # 查看npm版本(如10.2.3) - 第一个 Node.js 程序
创建 hello.js 文件,复制以下代码:
javascript
运行
// hello.js
// 控制台输出
console.log("Hello Node.js!");
// 异步定时器(Node.js 异步特性)
setTimeout(() => {
console.log("异步执行:2秒后输出");
}, 2000);
运行代码:
bash
运行
node hello.js
输出结果:
plaintext
Hello Node.js!
2秒后输出
异步执行:2秒后输出
二、核心模块:Node.js 内置功能
Node.js 提供丰富的内置模块,无需安装即可使用,以下是高频模块示例:
- 文件系统模块(fs):读写文件
javascript
运行
// fs.js
const fs = require("fs");
const path = require("path"); // 路径处理模块
// 1. 同步读取文件(简单场景)
try {
const data = fs.readFileSync(path.join(__dirname, "test.txt"), "utf8");
console.log("同步读取文件:", data);
} catch (err) {
console.error("读取失败:", err.message);
}
// 2. 异步读取文件(推荐,非阻塞)
fs.readFile(path.join(__dirname, "test.txt"), "utf8", (err, data) => {
if (err) {
console.error("异步读取失败:", err.message);
return;
}
console.log("异步读取文件:", data);
});
// 3. 写入文件
const content = "Hello Node.js 写入内容!";
fs.writeFile(path.join(__dirname, "output.txt"), content, (err) => {
if (err) {
console.error("写入失败:", err.message);
return;
}
console.log("文件写入成功!");
});
// 4. 追加内容到文件
fs.appendFile(path.join(__dirname, "output.txt"), "\n追加的内容", (err) => {
if (err) throw err;
console.log("内容追加成功!");
});
运行前准备:创建 test.txt 文件,写入任意内容,执行 node fs.js 即可测试。
- HTTP 模块:创建简易 Web 服务器
javascript
运行
// server.js
const http = require("http");
// 创建服务器
const server = http.createServer((req, res) => {
// 设置响应头
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
// 路由处理
if (req.url === "/" && req.method === "GET") {
res.end("
欢迎访问 Node.js 服务器
路径:/
");} else if (req.url === "/api/user" && req.method === "GET") {
// 返回JSON数据
res.writeHead(200, { "Content-Type": "application/json; charset=utf-8" });
res.end(JSON.stringify({
code: 200,
data: { name: "张三", age: 20 },
msg: "请求成功"
}));
} else {
res.writeHead(404);
res.end("
404 Not Found
");}
});
// 监听端口
const PORT = 3000;
server.listen(PORT, () => {
console.log(服务器运行在:http://localhost:${PORT});
});
运行服务器:
bash
运行
node server.js
访问测试:
首页:http://localhost:3000
接口:http://localhost:3000/api/user
- 路径模块(path):处理文件路径
javascript
运行
// path.js
const path = require("path");
// 当前文件路径
console.log("当前文件路径:", filename);
// 当前目录路径
console.log("当前目录路径:", dirname);
// 拼接路径(跨平台兼容)
const filePath = path.join(__dirname, "files", "test.txt");
console.log("拼接路径:", filePath);
// 解析路径
const parsedPath = path.parse(filePath);
console.log("解析路径:", parsedPath);
// 输出:{ root, dir, base, ext, name }
// 获取文件扩展名
console.log("文件扩展名:", path.extname(filePath)); // .txt
- 事件模块(events):自定义事件
Node.js 基于事件驱动,events 模块是核心:
javascript
运行
// events.js
const EventEmitter = require("events");
// 自定义事件发射器
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
// 监听事件
myEmitter.on("greet", (name) => {
console.log(你好,${name}!);
});
// 监听一次事件(仅触发一次)
myEmitter.once("onceEvent", () => {
console.log("该事件仅触发一次");
});
// 触发事件
myEmitter.emit("greet", "张三");
myEmitter.emit("onceEvent");
myEmitter.emit("onceEvent"); // 无输出(仅触发一次)
// 移除事件监听
const callback = (name) => console.log(移除前:${name});
myEmitter.on("removeTest", callback);
myEmitter.emit("removeTest", "李四");
myEmitter.off("removeTest", callback);
myEmitter.emit("removeTest", "李四"); // 无输出
三、NPM 包管理:Node.js 生态核心
NPM 是 Node.js 自带的包管理器,用于安装 / 管理第三方依赖,核心命令如下:
- 基础命令
bash
运行初始化项目(生成package.json)
npm init -y # -y 跳过交互,直接生成
安装包
npm install axios # 本地安装(项目内)
npm install -g nodemon # 全局安装(系统级)
npm install express@4.18.2 # 指定版本安装
卸载包
npm uninstall axios
更新包
npm update axios
查看已安装包
npm list # 本地包
npm list -g --depth=0 # 全局包(仅显示顶层)
- 实战:使用 Express 搭建 Web 服务
bash
运行安装Express
npm install express
创建 express-server.js,复制以下代码:
javascript
运行
// express-server.js
const express = require("express");
const app = express();
const PORT = 3000;
// 中间件:解析JSON请求体
app.use(express.json());
// 路由:GET请求
app.get("/", (req, res) => {
res.send("
Express 服务器
");});
// 路由:GET请求返回JSON
app.get("/api/user", (req, res) => {
res.json({
code: 200,
data: { name: "张三", age: 20 },
msg: "请求成功"
});
});
// 路由:POST请求
app.post("/api/login", (req, res) => {
const { username, password } = req.body;
if (username === "admin" && password === "123456") {
res.json({ code: 200, msg: "登录成功" });
} else {
res.json({ code: 400, msg: "账号或密码错误" });
}
});
// 启动服务器
app.listen(PORT, () => {
console.log(Express服务器运行在:http://localhost:${PORT});
});
运行服务器:
bash
运行
node express-server.js
测试接口:
GET:http://localhost:3000/api/user
POST:http://localhost:3000/api/login(请求体:{"username":"admin","password":"123456"})
四、实战示例:文件上传 + API 服务
bash
运行
安装依赖
npm install express multer cors
创建 app.js,复制以下代码:
javascript
运行
// app.js
const express = require("express");
const multer = require("multer");
const cors = require("cors");
const fs = require("fs");
const path = require("path");
const app = express();
const PORT = 3000;
// 跨域中间件
app.use(cors());
// 解析JSON
app.use(express.json());
// 静态文件目录(上传的文件可访问)
app.use("/uploads", express.static(path.join(__dirname, "uploads")));
// 创建uploads目录(不存在则创建)
if (!fs.existsSync(path.join(dirname, "uploads"))) {
fs.mkdirSync(path.join(dirname, "uploads"));
}
// 配置文件上传
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, path.join(__dirname, "uploads"));
},
filename: (req, file, cb) => {
// 自定义文件名:时间戳+原文件名
const fileName = ${Date.now()}-${file.originalname};
cb(null, fileName);
}
});
const upload = multer({ storage });
// 1. 文件上传接口
app.post("/api/upload", upload.single("file"), (req, res) => {
if (!req.file) {
return res.json({ code: 400, msg: "请选择文件" });
}
// 返回文件访问路径
const fileUrl = http://localhost:${PORT}/uploads/${req.file.filename};
res.json({
code: 200,
msg: "上传成功",
data: {
fileName: req.file.filename,
fileSize: req.file.size,
fileUrl
}
});
});
// 2. 获取文件列表接口
app.get("/api/files", (req, res) => {
fs.readdir(path.join(__dirname, "uploads"), (err, files) => {
if (err) {
return res.json({ code: 500, msg: "获取文件列表失败" });
}
// 拼接文件访问路径
const fileList = files.map(file => ({
name: file,
url: http://localhost:${PORT}/uploads/${file}
}));
res.json({
code: 200,
data: fileList
});
});
});
// 启动服务器
app.listen(PORT, () => {
console.log(应用运行在:http://localhost:${PORT});
console.log("文件上传接口:POST /api/upload");
console.log("文件列表接口:GET /api/files");
});
运行与测试
启动应用:node app.js;
测试文件上传(Postman):
请求方式:POST;
地址:http://localhost:3000/api/upload;
请求体:form-data,key 为file,选择任意文件上传;
查看文件列表:访问 http://localhost:3000/api/files。
五、核心特性与避坑指南
- 核心特性
异步非阻塞 I/O:文件读写、网络请求等操作不阻塞主线程,适合高并发场景;
单线程:主线程处理逻辑,异步操作由 Libuv 线程池处理,避免线程切换开销;
事件驱动:基于事件循环(Event Loop),异步操作完成后触发回调;
跨平台:支持 Windows/Mac/Linux,代码一次编写多端运行;
丰富的生态:NPM 拥有百万 + 第三方包,覆盖各类场景。 - 常见坑点
(1)回调地狱
多层异步回调嵌套导致代码难以维护,优化方案:
javascript
运行
// 原始回调(不推荐)
fs.readFile("1.txt", (err, data1) => {
fs.readFile("2.txt", (err, data2) => {
fs.readFile("3.txt", (err, data3) => {
// 多层嵌套
});
});
});
// 优化:Promise + async/await(推荐)
const readFile = (path) => {
return new Promise((resolve, reject) => {
fs.readFile(path, "utf8", (err, data) => {
err ? reject(err) : resolve(data);
});
});
};
const readFiles = async () => {
try {
const data1 = await readFile("1.txt");
const data2 = await readFile("2.txt");
console.log(data1, data2);
} catch (err) {
console.error(err);
}
};
(2)同步操作慎用
fs.readFileSync 等同步方法会阻塞主线程,仅适合启动时初始化。
(3)端口占用
启动服务器提示 EADDRINUSE 时,解决方法:
bash
运行
Windows
netstat -ano | findstr :3000 # 查找进程ID
taskkill /PID 进程ID /F # 杀死进程
Linux/Mac
lsof -i :3000 # 查找进程ID
kill -9 进程ID # 杀死进程
- 生产环境优化
使用 pm2 管理进程(自动重启、负载均衡):
bash
运行
npm install -g pm2
pm2 start app.js --name "node-app"
pm2 list # 查看进程
pm2 restart node-app # 重启
pm2 logs # 查看日志
配置环境变量区分开发 / 生产环境;
全局捕获异常,避免服务崩溃;
使用 winston/log4js 记录日志。
总结
Node.js 凭借异步非阻塞特性和丰富的生态,成为全栈开发的核心技术。掌握其内置模块、NPM 包管理和异步编程模式,可轻松构建高性能的后端服务、CLI 工具和全栈应用。