Node.js新手教程:从零开始学习服务器端JavaScript
写在开头:这不是一篇冷冰冰的“技术文档”,而是一个普通程序员的真实记录。如果你也曾焦虑、迷茫,甚至怀疑自己能不能行——希望这篇文章能给你一点温暖和方向。
1. 那个周末,我和老婆视频时差点哭出来
去年十月的一个周五晚上,我在出租屋里啃着泡面,盯着屏幕上那道“手写一个简易 HTTP 服务器”的面试题发呆。窗外北京的风刮得呼呼响,房租3500块的房子连暖气都不太灵光。
手机突然震动,是老婆打来的视频。她刚加完班,眼睛有点红:“你最近还好吗?看你朋友圈都没怎么更新。”
我强笑着:“挺好的啊,刚学完 Express,准备搞个 Todo 应用练手。”
她说:“别骗我了,你每次说‘挺好的’,其实都在硬撑。”
我沉默了几秒,鼻子一酸:“……真的好难。Node.js 的事件循环、异步回调、Stream 流……面试官问的我全懵了。上周三面挂了,HR 说‘基础不扎实’。”
她没说话,只是轻声说:“要不……回老家找份稳定工作?离我也近点。”
我知道她是心疼我。我们异地快一年了,每月见面就两天。我月薪15k,在北京勉强活着;她22k在深圳,却总担心我吃不好睡不好。
但我不甘心。
我不是科班出身,三年前还是个手动点按钮的测试工程师。为了转开发,我熬过无数个深夜,啃《JavaScript高级程序设计》,刷 LeetCode,做开源项目……好不容易进了开发岗,怎么能因为一个 Node.js 就退回去?
那天挂掉电话后,我擦了擦眼睛,打开 VS Code,新建了一个 server.js 文件。
我对自己说:这次,我要从“零”真正开始。
2. 为什么是 Node.js?因为它“亲民”
说实话,当初选 Node.js 不是因为多酷,而是——它门槛低。
作为前端熟悉的 JavaScript,能直接写后端,不用再学一门新语言(比如 Java 或 Python),对我们这种半路出家的人来说,简直是救命稻草。
但“会写”和“懂原理”完全是两回事。
我之前犯的最大错误,就是以为“会用 Express 搭个 API”就等于“会 Node.js”。结果面试一问底层机制——事件循环怎么工作?process.nextTick 和 setImmediate 区别?Stream 背压怎么处理?——我直接哑火。
于是,我决定推倒重来。
第一步:别急着用框架,先写原生 HTTP 服务器
// server.js
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello, I\'m not using Express!');
});
server.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
就这么十几行代码,我花了整整一个周末研究:
http.createServer到底做了什么?req和res是什么对象?继承自哪里?- 为什么
res.end()必须调用?不调用会怎样?
我甚至去翻了 Node.js 官方源码(GitHub 上的 node/lib/_http_server.js),虽然看得头晕,但至少明白了:框架只是糖衣,核心逻辑永远在底层。
第二步:搞懂“异步”不是口号
以前写前端,async/await 用得很溜,以为后端也一样。
但 Node.js 的异步模型更复杂——它基于 事件循环(Event Loop),而事件循环又分多个阶段(timers、I/O callbacks、poll、check、close 等)。
我画了一张草图贴在墙上,每天看一眼:
[Timers] → [I/O Callbacks] → [Poll] → [Check] → [Close]
↑___________________________↓
然后写了个小程序验证:
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
process.nextTick(() => console.log('nextTick'));
// 输出顺序:nextTick → timeout → immediate
// (实际顺序可能因环境而异,但 nextTick 一定最先)
这个小实验让我明白:面试题不是刁难你,而是看你是否理解运行机制。
后来我整理了一份《Node.js 常见面试题清单》,包括:
- 事件循环的执行顺序?
- 如何避免回调地狱?
- Cluster 模块如何实现多进程?
- Stream 有哪几种类型?背压怎么处理?
我把这些问题打印出来,贴在书桌前。每搞懂一个,就划掉一个。那种“打怪升级”的感觉,莫名上瘾。
3. 教程之外:安全意识才是底线
很多人学 Node.js,只关注“怎么跑起来”,却忽略了安全。
我吃过亏。
去年十一月,我用 Express 写了个简单的用户注册接口,为了省事,直接拼接 SQL:
// 千万别这么写!
app.post('/register', (req, res) => {
const { username, password } = req.body;
db.query(`INSERT INTO users VALUES ('${username}', '${password}')`);
});
结果被同事当场抓包:“兄弟,你这是给黑客送礼啊!SQL 注入分分钟拖库。”
我脸一下红了。
从此以后,我给自己定下铁律:任何用户输入,必须校验、过滤、转义。
后来我学到几条 Node.js 安全最佳实践:
- 用
helmet中间件加固 HTTP 头 - 密码必须用
bcrypt加盐哈希 - 禁止直接暴露错误信息(比如数据库报错)
- 使用
express-validator校验参数 - 依赖包定期用
npm audit扫描漏洞
这些内容,我全都加进了自己写的《Node.js 新手安全入门教程》里。虽然只有 8 页 PDF,但这是我用“血泪”换来的经验。
4. 转机:从“能跑”到“能扛”
今年三月,我接到一家跨境电商公司的终面邀请。
面试官是个戴眼镜的中年大哥,上来就问:“如果用户上传一个 10GB 的文件,你的服务会不会崩?”
我心跳加速,但没慌。
我详细讲了怎么用 stream 分块读取,怎么用 pipeline 自动处理背压,怎么限制文件大小和类型,甚至提到用 sharp 做图片压缩防爆内存。
他点点头:“你还真研究过。”
一周后,HR 打来电话:“我们愿意给 22k,base 北京,可远程两天。”
我握着手机,手都在抖。
当晚就订了高铁票,周末去深圳见老婆。
在车上,我给她发消息:“我们不用异地了。新工作支持混合办公,我可以每月去你那边住两周。”
她回了个哭笑表情:“臭小子,终于熬出头了?”
5. 给正在路上的你:几点真心话
如果你也在学 Node.js,或者正处在职业转型的焦虑中,我想分享几点感悟:
① 别怕“慢”,怕的是“假装努力”
我见过太多人收藏一堆“三天精通 Node.js”教程,却从不动手写一行代码。
真正的成长,是在 console.log 里 debug 到凌晨三点,是在 GitHub 提交记录里看到连续 60 天的绿色方块。
② 面试题不是敌人,是地图
每一道面试题背后,都藏着一个知识盲区。
把它当成闯关游戏,答错不可耻,不懂装懂才可怕。
③ 安全是开发者的尊严
你能写出炫酷的功能,但如果系统被黑、用户数据泄露,所有努力都会归零。
安全不是附加项,是默认项。
④ 技术之外,还有生活
我曾以为“拼命 coding”就是全部,直到看到老婆眼里的担忧。
现在我每天 9 点准时关电脑,陪她视频半小时。技术可以补,感情不能等。
6. 最后:写给未来的自己
现在的我,依然不是什么大神。
Node.js 的源码我只看懂了冰山一角,分布式、微服务、性能优化……还有很多山要爬。
但我不再焦虑了。
因为我明白:成长不是一跃登天,而是一步一脚印。
下周,我打算开源一个“安全优先”的 Node.js 脚手架,名字就叫 safe-node-starter。里面集成了基础的安全配置、日志监控、错误处理——送给每一个像我一样从零开始的人。
如果你也在路上,欢迎 star,也欢迎留言吐槽。
技术这条路孤独,但我们可以彼此照亮。
P.S. 这篇教程写了整整三个晚上,期间老婆还给我点了外卖(谢谢亲爱的)。
如果你觉得有用,不妨转发给那个正在挣扎的朋友——也许,你的一次分享,就能让他少走半年弯路。
P.P.S. 下个月,我和老婆打算一起去云南旅行。她说:“你写代码的样子很帅,但笑起来更帅。”
我想,这就是坚持的意义吧。

评论 0