Node.js 干了一件事:把 JavaScript 从浏览器里放出来。以前 JS 只能写网页里那点交互,现在它能写服务器、写命令行工具、写桌面应用、甚至写数据库客户端。一套语言,前后端通吃。这一页从装环境讲到部署上线,按 Node.js 22 LTS / 24 LTS 的现代写法,带你把"会一点 JS"升级成"能写后端服务"。
本页目录 · 十六站,一站都别跳
为什么学 Node.js,怎么把它装上
2009 年之前,JavaScript 是个"只能待在浏览器里的玩具"。一个叫 Ryan Dahl 的家伙把 Chrome 的 V8 引擎扒下来,外面包了一层能操作文件、能发网络请…
模块系统:代码怎么拆、怎么拼
一个项目不可能全写在一个文件里——那就是个几千行的大泥球,改一行心慌半天。模块系统就是"把代码切成小文件、互相引用"的规则。Node 历史上有两套规则:祖传的 CommonJS(r…
包管理器:npm、pnpm、yarn 怎么选
npm 是 Node 亲儿子,自带;pnpm 和 yarn 是后来者,主打"更快、更省磁盘"。它们干的是同一件事:把别人写好的代码包,下载下来放到你项目的 node_modules…
异步编程与事件循环:Node 的魂
这一章是 Node.js 最核心、也最容易把人绕晕的地方。先记住一句话:Node 是单线程的,但它能同时招呼一万个请求——秘诀就是"不等"。读文件、查数据库、发网络请求这些"要等"…
内置核心模块:Node 白送的工具箱
写 Node 不用装任何包,它自己就带了一大堆内置模块:读写文件、拼路径、起 HTTP 服务、加密、处理二进制、调子进程……下面挑你天天用的几个讲,require 就能用,不花一分…
Express:最流行的 Web 框架
上一章那个原生 http 服务器,自己判断 if(req.url === '/') 写不了几行就乱套。Express 就是把这些脏活打包好的框架——你只要说"GET 这个路径时干嘛…
NestJS:企业级的 Node 框架
Express 灵活但自由过头——项目一上千行,代码怎么组织全靠自觉,十人团队能写出十种风格。NestJS 就是来"定规矩"的:它强制用 TypeScript,内置依赖注入、装饰器…
数据库访问:数据往哪儿存
光有接口不存数据,接口就是个空壳。这一章讲 Node 怎么连数据库:关系型数据库(MySQL/PostgreSQL,表格思维)、NoSQL(MongoDB,文档思维)、缓存(Red…
测试、调试与日志
能跑的代码只是半成品,敢改的代码才是成品。怎么敢改?靠测试兜底。这一章讲用什么测、出问题怎么定位、线上怎么记日志。
部署与生产环境:从跑起来到扛住流量
本地跑通不算本事,放到公网上、半夜三点挂了能自动重启、被人攻击能扛住,才算上线。这一章讲进程管理、容器化、环境变量、安全清单和反向代理。
小项目实战:博客 API
前面十章都是零件,这一章把它们拼成一台真车:用 Express + Prisma + SQLite + JWT 写一个博客后端——用户注册登录、文章增删改查、评论、分页、搜索。SQ…
Web 框架对照:Express / Fastify / NestJS 怎么选
前面第 6 章讲了 Express,第 7 章讲了 NestJS,但你可能还是没底:到底该用哪个?Fastify 是不是"更快的 Express"?NestJS 是不是"过度设计"…
gRPC 与 GraphQL:Node 里的另外两种接口形态
你一定已经会写 REST 了。但工作两三年后,几乎必然会遇到这两个词:GraphQL(前端说"我要什么字段就给我什么,别给我一堆用不上的")和 gRPC(后端说"服务之间调来调去,…
TypeScript in Node:类型、构建与运行时校验
Node 项目写 TS 和后端同学想象的"编译型语言"不太一样:TS 的类型在运行时全部消失,它只在编译期帮你检查。这就带来一个关键结论:类型安全 ≠ 运行时安全。数据库返回的 J…
安全与限流:helmet、JWT 校验、限流与凭据
第 10 章有一份安全清单,这一章把它变成能直接抄进代码的配置。Node 服务天然暴露在公网,而且绝大多数事故不是因为"被高级攻击者盯上",而是因为默认配置没人改:响应头没加、接口…
常见坑与避雷指南
最后把新手最容易栽的七个坑集中摆出来。这些坑每个线上项目都有人踩过,你提前知道,就比别人少熬几个夜。
Node 15 以后,一个 Promise 报错没人 catch,整个进程直接退出。线上表现就是服务莫名崩溃。解法:每个 await 都包 try/catch,全局再加一个 process.on('unhandledRejection') 兜底记日志。
Node 单线程,你在请求处理里写个"算 100 万次"的死循环,所有其他请求全部卡死。解法:CPU 密集的活丢给 worker_threads(工作线程)或 child_process(子进程),别让主线程干重活。
又说一遍,因为太容易犯:fs.readFileSync、jwt.sign 之外的同步操作,放在 Express 接口里就是阻塞所有人。一律用异步版。
三种最常见:① 模块级全局变量不停塞数据;② EventEmitter.on 订阅了从不 removeListener;③ 流用完不关。解法:用 --inspect 跑 Chrome 内存快照对比,或定期监控 RSS 内存曲线。
只提交 package.json 不提交 lock 文件,同事 npm install 装到的版本和你不一样,bug 莫名其妙。解法:package-lock.json / pnpm-lock.yaml 必须进 git。
nodemon 和 --watch 是开发工具,监听文件变化自动重启。生产环境用它们:多耗一份资源,还可能误重启。解法:生产用 PM2 或 systemd 管进程,重启策略交给它们。
在异步回调里随手改共享的 req 对象,多个请求交错执行时会读到别人的值,出现"串号"灵异 bug。解法:每个请求的状态放独立的局部变量,别往 req 上挂自己的东西。
1.(概念题)为什么 Node.js 适合写高并发的网络服务,而不适合做 CPU 密集的计算?
查看答案
答案:Node 是单线程 + 非阻塞事件循环。网络服务大量时间花在"等"(等数据库、等下游),Node 等的时候去处理别的请求,一个进程能同时挂着几千个连接。但 CPU 密集任务会占死那唯一的主线程,其他请求全卡住,所以这类活要丢给 worker_threads 或子进程。
2.(执行顺序题)下面这段代码,console 按什么顺序打印?
查看答案
答案:A → D → C → B。解析:先跑同步代码 A、D;同步结束后清空所有微任务,Promise.then 的 C 执行;最后才轮到宏任务 setTimeout 的 B。哪怕 setTimeout 时间是 0,也排在微任务后面。
3.(排错题)新手在 Express 里写了 app.post('/login', (req,res)=>{ console.log(req.body) }),发 JSON 请求过去,发现 req.body 是 undefined。问题出在哪?
查看答案
答案:忘了加 app.use(express.json()) 这个中间件。Express 不会自动解析 JSON 请求体,必须在路由之前挂上 express.json(),req.body 才有内容。这是 Express 新手第一坑。
4.(选型题)你要写一个每天给 1000 个用户发提醒邮件的小脚本,读一个本地 SQLite 库。下面两套说法哪个对?
甲:用 Express + 集群模式 + Nginx 部署;
乙:写个普通 Node 脚本,用 node-cron 定时跑就行。
查看答案
答案:乙。解析:不是所有 Node 项目都需要 Express。"发邮件"是个定时批处理任务,不是对外提供 HTTP 接口,根本不需要起 Web 服务器。Express 是"写 API/网站"时才用的工具,别为了用框架而用框架。工具要匹配问题。
5.(安全题)下面这段登录校验代码有什么严重问题?const sql = "SELECT * FROM users WHERE email='" + inputEmail + "'";
查看答案
答案:SQL 注入漏洞。如果攻击者输入 ' OR 1=1 --,拼出来的 SQL 就变成永真条件,能绕过登录甚至拖库。正确做法:用参数化查询(WHERE email = ? + 参数数组)或 ORM,让驱动自动转义,永远不要用字符串拼接用户输入。
① 你已经能从装环境一路讲到部署上线:模块、包管理、异步、内置模块、Express、NestJS、数据库、测试、PM2/Docker。
② 接下来别停:把第 11 章的博客 API 完整做一遍,再加个评论和编辑,然后试着用 PM2 跑起来。
③ Node 是工具,用它解决你自己的一个真问题——爬虫、小工具、个人博客后端——比再看十篇教程都管用。