Node.js新手教程:从零开始学习服务器端JavaScript
上周五晚上十点半,我正一边改着祖传的 jQuery 代码(对,你没看错,2024年了我们组还在维护一个十年前的后台管理系统),一边刷着考公的行测题。产品经理突然在群里@我:“这个接口下周上线,Node 写的,你不是说想学新东西吗?正好练练手!”——我差点把刚泡好的枸杞茶打翻在机械键盘上。
说实话,作为一个每天和 Rust 生命周期搏斗、梦想着“上岸”逃离996的在职程序员,我对 JavaScript 的感情很复杂。前端那套我熟得很,但服务端?我之前一直觉得那是 PHP 和 Java 老哥们的地盘。不过既然领导发话了,加上 GitHub 上好多开源项目都用 Node 做后端,再不学就真要被时代甩下车了。于是,我决定从零开始搞个能跑起来的 Node.js 项目,顺便写篇文章记录一下踩坑过程,给同样“被迫成长”的兄弟们参考。
为啥是 Node.js?别问,问就是需求驱动
我们组最近接了个新活儿:要做一个内部工具平台,用来管理各种自动化脚本的执行状态。前端用 Vue3 + TypeScript(这块我熟),但后端呢?老系统是 PHP,新微服务又得对接 Java,运维大哥一听又要部署新语言就头大。这时候组长一拍大腿:“用 Node 吧!你们前端都会 JS,学起来快,还能统一技术栈!”——结果锅就落到了我头上。
其实我早就在 VSCode 里装了一堆 Node 相关插件(比如 ESLint、Prettier、npm Intellisense),只是从来没真正跑过一个完整的服务端项目。这次算是被逼上梁山了。
环境搭建:别让第一步就劝退你
首先得有个 Node 环境。我本地用的是 macOS,直接去官网下 LTS 版就行。但如果你像我同事小王一样用 Windows(他说是因为打游戏),建议用 nvm-windows 来管理版本,不然以后升级降级能把你整疯。
装完后验证一下:
node -v
# v18.17.0 (LTS 版本)
npm -v
# 9.6.7
血泪教训:千万别直接用系统自带的 Node!我上次在 Linux 服务器上用 yum 装的 Node,版本太老,连 ES Module 都不支持,调试到凌晨三点才发现问题出在这儿。运维大哥还嘲笑我:“你是不是没看过文档?” —— 我当时真的想砸电脑。
第一个“Hello, World!”:比想象中简单
新建一个目录,比如叫 node-starter,然后初始化项目:
mkdir node-starter && cd node-starter
npm init -y
这会生成一个 package.json 文件,里面记录了你的项目信息和依赖。接着创建 index.js:
// index.js
console.log('Hello, 公务员考试培训班!');
运行:
node index.js
搞定!虽然简单得有点尴尬,但这一步很重要——至少证明你的环境没问题。我第一次运行时因为用了 console.log("你好") 结果终端显示乱码,查了半天发现是 iTerm2 的编码设置问题……这种低级错误千万别学我。
搞个真正的 HTTP 服务器:Express 出场
光打印日志可没法交差。我们需要一个能响应 HTTP 请求的服务器。这时候就得请出 Node.js 生态里最流行的框架:Express。
安装它:
npm install express
然后重写 index.js:
// index.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
// 最简单的路由
app.get('/', (req, res) => {
res.send('恭喜你!成功逃离了前端,进入了更卷的服务端世界!');
});
// 启动服务器
app.listen(PORT, () => {
console.log(`服务器跑起来了!访问 http://localhost:${PORT}`);
});
运行 node index.js,浏览器打开 http://localhost:3000,看到那行字的时候,我居然有点小激动——这可是我人生第一个 Node 服务端程序啊!
中间件:Express 的灵魂
Express 强大的地方在于中间件(Middleware)。你可以把它理解成流水线上的一个个处理站。比如我们要加个日志功能:
// 日志中间件
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
next(); // 别忘了调用 next(),否则请求会卡住!
});
真实场景吐槽:上周我忘了写 next(),导致所有接口都超时,测试妹子疯狂@我:“接口挂了!”,我查了半小时才发现是这个低级错误。后来我在 VSCode 里专门给 next() 加了 snippet,输入 nx 就自动补全,再也不怕忘了。
处理 JSON 数据:前后端联调的关键
现在前端基本都用 JSON 交互,所以我们得让 Express 能解析 JSON 请求体:
// 解析 JSON
app.use(express.json());
// 测试 POST 接口
app.post('/api/data', (req, res) => {
console.log('收到数据:', req.body);
res.json({ message: '收到啦!', yourData: req.body });
});
用 Postman 或 curl 测试一下:
curl -X POST http://localhost:3000/api/data \
-H "Content-Type: application/json" \
-d '{"name": "考公人", "status": "焦虑"}'
返回:
{
"message": "收到啦!",
"yourData": {
"name": "考公人",
"status": "焦虑"
}
}
完美!这样前后端就能愉快地联调了。我们组之前有个接口因为没加 express.json(),前端传的 JSON 被当字符串处理,结果数据库存了一堆 [object Object],线上事故复盘会上产品经理的脸都绿了……
项目结构优化:别把所有代码塞进一个文件
随着功能增加,index.js 会越来越臃肿。我参考了 GitHub 上一些 star 很高的项目(比如 express-generator 生成的结构),把代码拆分了一下:
node-starter/
├── package.json
├── server.js # 启动入口
├── app.js # Express 应用配置
├── routes/
│ └── index.js # 路由定义
└── middleware/
└── logger.js # 自定义中间件
app.js:
const express = require('express');
const indexRoutes = require('./routes/index');
const app = express();
// 中间件
app.use(require('./middleware/logger'));
app.use(express.json());
// 路由
app.use('/', indexRoutes);
module.exports = app;
server.js:
const app = require('./app');
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`服务器启动成功!端口: ${PORT}`);
});
这种结构清晰多了,也方便团队协作。我们组长看了直点头:“嗯,有模有样了,不像刚学的。”
工具链:提升开发效率的神器
作为重度 VSCode 用户,我必须安利几个 Node 开发必备插件:
- ESLint: 自动检查代码规范,避免低级错误
- Prettier: 一键格式化,拯救缩进强迫症
- REST Client: 在 VSCode 里直接发 HTTP 请求,不用切 Postman
- npm Intellisense: 输入
npm install时自动提示包名
另外,开发时频繁重启服务很烦,所以我加了 nodemon:
npm install --save-dev nodemon
然后在 package.json 里加个 script:
{
"scripts": {
"dev": "nodemon server.js",
"start": "node server.js"
}
}
现在运行 npm run dev,代码一改,服务自动重启,爽歪歪!
连接真实数据:模拟一个用户 API
为了更贴近实战,我用内存数组模拟一个用户数据库(生产环境当然要用 MongoDB 或 PostgreSQL):
// routes/users.js
const express = require('express');
const router = express.Router();
let users = [
{ id: 1, name: '张三', job: '程序员' },
{ id: 2, name: '李四', job: '考公人' }
];
// GET /api/users
router.get('/', (req, res) => {
res.json(users);
});
// POST /api/users
router.post('/', (req, res) => {
const newUser = {
id: users.length + 1,
...req.body
};
users.push(newUser);
res.status(201).json(newUser);
});
module.exports = router;
然后在 app.js 里挂载:
const userRoutes = require('./routes/users');
app.use('/api/users', userRoutes);
现在你可以通过 /api/users 获取和创建用户了。虽然简单,但这就是 RESTful API 的基本套路。
部署上线:从本地到服务器
终于到了最刺激的环节——部署!我们公司用的是阿里云 ECS,我用 PM2 来管理进程:
npm install -g pm2
在服务器上拉取代码(记得先推到 GitHub):
git clone https://github.com/yourname/node-starter.git
cd node-starter
npm install
pm2 start server.js --name "my-node-app"
PM2 会保证你的应用崩溃后自动重启,还能查看日志:
pm2 logs my-node-app
真实故事:去年双11期间,我们一个 Node 服务因为内存泄漏挂了,多亏 PM2 自动重启,才没造成更大损失。运维大哥后来请我喝了杯瑞幸,说:“还是你们前端转后端的靠谱。”
总结:学 Node 对考公有帮助吗?
写完这个项目,我最大的感受是:Node.js 入门门槛确实低,尤其对我们前端来说,JS 语法无缝衔接。Express 框架简洁灵活,配合丰富的 npm 生态,能快速搭建出可用的服务。
至于考公……呃,好像没啥直接关系 😅。不过这段经历让我明白:技术栈广度很重要。公务员考试里也有计算机专业知识科目,说不定哪天就考到“什么是事件循环”呢?(开玩笑的)
更重要的是,通过这个项目,我学会了用服务端思维解决问题。以前只关心页面好不好看、按钮点不点得动,现在还会考虑接口性能、错误处理、日志监控。这种全局视角,无论以后是继续写代码还是真的“上岸”,都是宝贵财富。
最后放个 GitHub 地址,代码我都整理好了,欢迎 star/fork/提 issue: https://github.com/yourname/node-starter
(注:链接是示例,实际使用请替换为真实地址)
附:Node.js vs 其他后端语言速查表
| 特性 | Node.js | Python (Django) | Java (Spring) |
|---|---|---|---|
| 学习曲线 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 开发速度 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
| 并发处理 | ⭐⭐⭐⭐⭐ (事件驱动) | ⭐⭐ | ⭐⭐⭐⭐ |
| 生态丰富度 | ⭐⭐⭐⭐⭐ (npm) | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| 适合场景 | I/O 密集型、实时应用 | 数据分析、AI | 企业级大型系统 |
对我这种想快速交付内部工具的人来说,Node.js 真是香。好了,不说了,行测题还没刷完,梦想还是要有的,万一上岸了呢?

评论 0