1. 为什么我建议你在Windows上用Node.js写后端
先说结论:Windows完全能胜任Node.js后端开发,而且对于绝大多数中小型项目和业务系统来说,体验并不比macOS或Linux差太多。
我见过不少初学者被网上的言论吓住,总觉得“正经后端都得用Linux”,结果在Windows上畏手畏脚,甚至为了跑个Node.js先把系统换成了双系统。真没必要。Node.js本身就是跨平台的运行时,你在Windows上写的代码,部署到Linux服务器上照样能跑,唯一的差异集中在环境变量写法、文件路径分隔符、部分原生模块的编译这几个地方,后面我会逐个说。
那为什么选Node.js做后端?它最大的优势是“一门语言通吃前后端”。如果你已经会JavaScript,再去学后端逻辑,不需要切换语言心智,回调、Promise、异步流程这些概念在前端已经熟悉了,上手成本极低。就算你完全不会JavaScript,它的语法也足够直观,比起Java那一套类与接口的仪式感,Node.js更像是在“写逻辑”而不是“造架构”。
适合用Node.js做的后端场景也很明确:RESTful API服务、实时通信(WebSocket)、工具类中间服务、轻量级BFF层、物联网设备数据接入。它的短板在CPU密集型计算——比如图像处理、复杂算法这类场景,Node.js的单线程模型会吃大亏,这时候你该选Python或Go,而不是硬用Node.js扛。
再说Windows作为开发环境,有几个被低估的优点:PowerShell和Windows Terminal现在很好用,WSL(Windows Subsystem for Linux)随时可以切一套Linux环境跑命令,Docker Desktop在Windows上跑Linux容器也早已成熟。也就是说,你完全可以“在Windows上开发,在容器里运行”,两边的好处都占上。这篇文章的所有操作,我都基于纯Windows环境(不带WSL),这样门槛最低,也最贴合大多数新手实际面临的情况。
我会从安装Node.js这个最容易被忽视的第一步讲起,然后带着你完整地初始化一个项目、写一个能跑起来的HTTP服务、接上热重载和调试工具,最后把Windows上常见的坑和排查方法整理出来。整个过程会在Windows 11 + Node.js 20 LTS环境下演示,你不需要有任何后端基础,只需要会打开命令行就够了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备:安装Node.js的正确姿势与版本管理
2.1 选择LTS版本还是Current版本
打开Node.js官网,你会看到两个下载按钮:一个是LTS(长期支持版),一个是Current(当前最新版)。很多新手会下意识点那个写着“最新”的按钮,但这其实是个坑。
LTS版本是给生产环境用的,官方承诺长期维护,API稳定,生态里的第三方包兼容性最好。Current版本虽然有着最新的特性,但也意味着它刚上线不久,很多npm包还没来得及跟上,你在安装依赖时可能会遇到莫名其妙的编译报错。尤其是那些带原生C++模块的包(比如bcrypt、sharp),在Current版本上经常出幺蛾子。
我给你的建议非常直接:开发环境用LTS,想尝鲜新特性就另开一个目录用Current版本单独折腾。 不要在主项目里挑战最新版。
2.2 一步步完成安装
安装包没什么特别的,去官网下载Windows Installer(.msi)就行。需要注意的点集中在安装向导里:
- 安装路径建议保持默认(
C:\Program Files\nodejs\),或者改成D:\nodejs\也完全可以,避免路径中出现中文和空格。 - 向导里有个“Add to PATH”选项,默认是勾选的,一定要保持勾选。这一步会把Node.js的可执行文件路径写入系统环境变量,之后你才能在任何目录下直接使用
node命令。 - 向导里还有个选项是安装“Node.js runtime”和“npm package manager”,全部保持默认勾选。
- 如果向导询问是否安装“Tools for Native Modules”,也就是编译原生模块所需的Visual Studio Build Tools,我建议先跳过。等你真的遇到需要编译的包时再装也不迟,这时候装只会白白消耗时间和磁盘空间。
安装完成后,打开一个新的终端窗口(这一步很关键,旧窗口不会刷新环境变量),输入以下命令验证:
bash复制node -v
能输出类似v20.16.0的版本号,说明安装成功。接着验证npm:
bash复制npm -v
2.3 用nvm-windows管理多版本Node.js
如果你只是短暂地写个Demo,直接装一个LTS版本就够了。但如果你打算长期做Node.js开发,我强烈建议你现在把官方安装包卸了,换成nvm-windows来管理Node.js版本。
原因是现实工作中你几乎一定会遇到“这个老项目要用Node 14,那个新项目要用Node 20”的情况。没有版本管理工具,你就得反复卸载安装,光是环境变量出错就够你折腾一晚上。nvm-windows就是干这个的,它允许你在同一台机器上装多个Node.js版本,并随时切换。
安装步骤:
- 先去GitHub上搜
coreybutler/nvm-windows,下载最新版的nvm-setup.exe。 - 安装过程中有一步让你选择“Symlink”路径,这个路径是用来存放当前激活的Node.js版本的。默认是
C:\Program Files\nodejs,保持默认就行。 - 安装完成后打开新的终端,运行
nvm version验证是否安装成功。
常用命令就四个:
bash复制# 查看已安装的版本
nvm list
# 安装指定版本
nvm install 20.16.0
# 切换版本
nvm use 20.16.0
# 查看远程所有可用版本
nvm list available
切换到某个版本后,你再执行node -v就会看到对应版本号。npm会跟着Node.js版本自动切换,不需要额外操作。
提示:nvm-windows切换版本的本质是修改symlink的指向,所以不用手动改环境变量。如果你之前用官方安装包装过Node.js,建议先彻底卸载干净再装nvm-windows,否则可能出现两个Node.js抢PATH的情况,到时候
node -v输出的版本会忽上忽下,非常迷惑。
2.4 配置npm镜像源
npm默认从官方源下载包,在国内网络环境下速度可能不太理想。我建议一开始就配置成国内镜像源,省得后面每次装包都卡在那等很久。
bash复制# 查看当前源
npm config get registry
# 配置为淘宝镜像源
npm config set registry https://registry.npmmirror.com
关于镜像源,有个细节值得知道:registry.npmmirror.com是阿里云维护的npm官方镜像,同步频率很高,稳定性经过了多年考验。如果你在公司内网,还可以配置成公司私有的npm源,操作方式完全一样。
换完源之后,安装依赖包的速度会有一个质的提升。
3. 项目初始化:从npm init到package.json的深度理解
3.1 创建项目目录
环境搞定之后,找一个合适的位置创建项目目录。我个人习惯在D:\projects\下建一个文件夹,专门放代码项目,不给C盘添负担。
bash复制# 进入你打算放项目的目录,比如D盘
cd D:\projects
# 创建项目目录并进入
mkdir node-demo
cd node-demo
3.2 npm init的交互式问答
进入项目目录后,执行:
bash复制npm init
npm会抛出一系列问题,包括项目名称、版本号、描述、入口文件、git仓库等。如果你不想被问这一堆问题,可以直接用:
bash复制npm init -y
-y的意思是“你问什么都不用管,全部用默认值”,执行完会直接生成一个package.json文件。对于刚起步的项目,这种方式效率最高,后面需要改再手动改文件就行。
生成的package.json大概长这样:
json复制{
"name": "node-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
3.3 package.json里每个字段是干什么的
我见过太多人直接跳过package.json的理解,导致后面遇到问题时完全不知道怎么排查。这里花几分钟把核心字段说清楚:
name:项目名称,发布到npm上时用它作为包名,不发布的话随便起。version:项目版本号,遵循语义化版本规则(主版本.次版本.修订号),发布时不能重复。main:入口文件路径,其他模块通过require()引入你的项目时,加载的就是这个文件。scripts:命令脚本集合。你可以自定义命令,比如"start": "node index.js",之后在终端执行npm run start就等价于node index.js。这是整个文件里使用频率最高的字段之一。dependencies:项目运行时依赖的第三方包。安装包时加npm install 包名就会自动写入这里。devDependencies:开发时依赖的包。比如热重载工具、测试框架、构建工具,它们只在开发阶段使用,部署到生产环境时可以通过npm install --production跳过安装。安装时加-D或--save-dev就会写入这里。
3.4 安装Express框架
后端开发不可能只用Node.js自带的http模块从零写路由、处理静态文件、解析请求体,那是2012年的写法。现在主流的做法是使用框架,最经典的就是Express。
Express是Node.js生态里历史最悠久、用户量最大的Web框架,它的设计哲学非常朴素:路由、中间件、模板渲染,搞定这三件事就能搭建出绝大多数后端服务。尽管现在有更快更现代的框架(如Fastify、NestJS),但Express依然是新手的最佳切入点,原因是它的中间件机制清晰易懂,而且网上你能搜到的Node.js后端教程,十个里有八个是基于Express写的,跟着做不会踩到版本兼容的坑。
安装Express:
bash复制npm install express
安装完成后,你去项目目录下看,会多出一个node_modules文件夹和一个package-lock.json文件。
node_modules:存放所有已安装的包的实际文件,这个文件夹非常大,通常几百兆起步,千万不要手动去改里面的文件,也不要在版本控制工具里提交它。package-lock.json:锁定依赖的精确版本号,以及依赖的依赖的版本号。它的作用是保证任何人在任何时间npm install时,装出来的依赖树完全一致。这个文件建议提交到版本控制里。
3.5 创建.gitignore避免垃圾文件入库
如果你打算用Git管理代码,一开始就要建一个.gitignore文件,否则node_modules会被整个提交上去,一次提交几百MB不说,还会拖垮仓库性能。
在项目根目录创建.gitignore,写入以下内容:
gitignore复制node_modules/
.env
.log
这行配置的意思很简单:忽略node_modules目录、.env环境变量文件和所有的日志文件。后面按需补充其他忽略规则。
3.6 项目目录结构规划
一个入门级的Node.js后端项目,目录结构尽量简单清晰,不要过度设计。我的建议是这样:
text复制node-demo/
├── src/ # 源码目录
│ ├── routes/ # 路由定义
│ │ └── index.js
│ ├── controllers/ # 业务控制器(处理具体逻辑)
│ ├── services/ # 业务服务层(可选,逻辑复杂时再加)
│ ├── models/ # 数据模型
│ ├── middlewares/ # 自定义中间件
│ └── app.js # Express应用实例
├── node_modules/ # 依赖包(不要动)
├── .gitignore
├── package.json
└── .env # 环境变量配置文件
新手最容易犯的错是“一上来就分层”,把routes、controllers、services、models全部建好,然后每个文件里只有两行代码。更好的做法是:先把功能跑通,等代码开始膨胀了,再按需拆结构和分目录。过早的结构设计只会让你在做每个小功能时都要想着“该放哪个文件夹”,分散了学习核心逻辑的注意力。
4. 从零手写第一个能跑的HTTP服务
4.1 用Node.js原生http模块打个底
虽然最终会用Express,但我还是建议先用Node.js原生http模块跑一个最简单的服务,理解HTTP服务最底层的机制。这样等你用Express时,很多东西就能对号入座。
在项目根目录创建index.js:
javascript复制const http = require('http');
const server = http.createServer((req, res) => {
// 给请求方返回一段文本
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('Hello, Node.js Server!');
});
// 监听3000端口
server.listen(3000, () => {
console.log('Server is running at http://localhost:3000');
});
终端里执行:
bash复制node index.js
然后打开浏览器访问http://localhost:3000,你会看到页面上显示Hello, Node.js Server!。
这个代码的逻辑很原始:createServer接收一个回调函数,每次有请求进来,回调函数就执行一次,req包含请求信息(URL、请求头、请求方法等),res负责返回响应。它演示了HTTP服务的核心:接收请求、处理逻辑、返回响应。但你也看到了,用原生模块写路由非常痛苦,因为你要自己解析URL、自己判断方法、自己处理各种边界情况。这也就是为什么我们接下来要用Express。
先Ctrl + C停掉这个进程,我们进入正题。
4.2 用Express重构服务
用Express改写上面的服务,我们先创建一个入口文件。通常我会把Express应用的构建逻辑放在src/app.js里,然后在根目录的index.js(或server.js)里负责启动监听。这样做的目的是把“应用配置”和“服务启动”解耦,后面做测试时可以直接引入app而不需要真正启动端口。
创建src/app.js:
javascript复制const express = require('express');
// 创建Express应用实例
const app = express();
// 解析请求体为JSON格式(中间件)
app.use(express.json());
// 定义一个GET路由
app.get('/', (req, res) => {
res.json({
message: 'Welcome to Node.js Backend Service',
timestamp: new Date().toISOString(),
});
});
// 导出app,供其他模块引入
module.exports = app;
再修改根目录的index.js:
javascript复制const app = require('./src/app');
// 设置监听端口,优先使用环境变量,默认3000
const PORT = process.env.PORT || 3000;
// 启动服务
app.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`);
});
然后在终端执行:
bash复制node index.js
再访问http://localhost:3000,你会看到返回了一个JSON对象。注意到区别没有?Express帮你做了几件事:
- 路由系统:你只需要指定路径和HTTP方法,框架自动匹配。
- 响应逻辑:
res.json()方法自动设置Content-Type为application/json并序列化数据。 - 请求解析:
express.json()中间件自动解析请求体,你不需要手动拼接字符串。
4.3 添加路由文件,告别堆代码
现在再增加一个用户相关的接口,演示如何把路由拆分到独立文件。
创建src/routes/users.js:
javascript复制const express = require('express');
// 创建路由实例
const router = express.Router();
// 模拟的内存数据
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
];
// 查询用户列表
router.get('/', (req, res) => {
res.json(users);
});
// 查询单个用户详情
router.get('/:id', (req, res) => {
const userId = Number(req.params.id);
const user = users.find((u) => u.id === userId);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
res.json(user);
});
// 新增用户
router.post('/', (req, res) => {
const { name } = req.body;
if (!name) {
return res.status(400).json({ message: 'Name is required' });
}
const newUser = {
id: users.length + 1,
name,
};
users.push(newUser);
res.status(201).json(newUser);
});
module.exports = router;
然后在src/app.js里注册这个路由:
javascript复制const express = require('express');
const usersRouter = require('./routes/users');
const app = express();
app.use(express.json());
// 注册用户相关路由,所有 /api/users 开头的请求都会交给 usersRouter 处理
app.use('/api/users', usersRouter);
app.get('/', (req, res) => {
res.json({
message: 'Welcome to Node.js Backend Service',
timestamp: new Date().toISOString(),
});
});
module.exports = app;
重启服务后,在终端里用curl测试一下:
bash复制# 获取用户列表
curl http://localhost:3000/api/users
# 获取id为1的用户
curl http://localhost:3000/api/users/1
# 新增用户
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name": "Charlie"}'
这里值得留意的是路由参数:id的用法。它表示这一段路径是动态的,req.params.id会拿到URL中实际传入的值。比如请求/api/users/1时,req.params.id就是字符串"1",所以要记得用Number()转成数字再跟users数组里的id做比较。
4.4 中间件的理解:请求的流水线处理
在刚才的代码里,我们已经用到了app.use(express.json())这个中间件。中间件是整个Express体系里最核心的概念,理解它对后面的开发至关重要。
你可以把中间件想象成一条流水线上的各个工位。一个HTTP请求从进入应用开始,会依次经过各个中间件,每个中间件可以决定3件事:
- 直接返回响应,结束请求流程;
- 对
req或res做修改,比如往req上挂载一个属性; - 调用
next(),把请求交给下一个中间件处理。
express.json()这个中间件的职责,就是读取请求体,尝试按JSON格式解析,解析成功后把结果挂到req.body上,然后调用next()让请求继续往下走。所以在路由处理函数里,你才能直接用req.body.name拿到数据。
自定义中间件也不难,比如加一个请求日志中间件,记录每次请求的方法、路径和耗时:
javascript复制// 日志中间件
app.use((req, res, next) => {
const start = Date.now();
// 等响应结束时打印日志
res.on('finish', () => {
const duration = Date.now() - start;
console.log(`${req.method} ${req.url} - ${duration}ms`);
});
next();
});
这个中间件放在app.use(express.json())之后、路由注册之前。这样任何一个请求进入时,都会先经过日志记录,再交给对应的路由处理。
中间件的顺序是有讲究的,从上到下依次匹配。通常习惯是:全局中间件放最上面(日志、JSON解析、跨域处理),然后才是路由。因为路由一旦匹配成功并返回响应,后面的中间件就不会再执行了。
4.5 启动脚本:让npm run start跑起来
目前启动服务用的是node index.js,为了更规范,我们把启动命令写进package.json的scripts字段里。
json复制{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
}
关于dev脚本里的nodemon,下一节专门讲。
5. 开发调试与热重载:解决每次改代码都要重启的问题
5.1 用nodemon实现自动重启
你刚才应该已经感受到了一个痛点:每次修改代码,都要Ctrl + C停掉服务,再重新node index.js才能看到效果。这在项目小的时候还能忍,等代码量上来之后,频繁重启会严重打断思路。
nodemon的作用就是监听项目文件的变化,一旦检测到文件被修改,自动重启Node.js服务。它解决的是“开发时反复手动重启”的问题。
安装并配置:
bash复制npm install -D nodemon
注意我这里加了-D,这是因为nodemon只是开发时使用的工具,生产环境启动直接node index.js就行,不需要它。
安装完成后,在package.json里加上dev脚本:
json复制{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
}
}
然后执行:
bash复制npm run dev
看下终端输出,nodemon启动后会显示类似[nodemon] watching path的信息。现在你修改src/app.js里的任何文字,保存之后,终端会自动触发重启,几秒之后新代码就生效了。
注意:
nodemon默认会监听当前目录下的所有文件变化。如果你需要排除某些目录(比如node_modules和dist),可以在项目根目录创建一个nodemon.json文件:
json复制{
"ignore": ["node_modules", "dist"]
}
5.2 VS Code调试:直接在编辑器里打断点
如果你只用console.log来调试,我只能说这还停留在初级阶段。VS Code自带了一套完整的Node.js调试工具,支持直接打断点、查看变量值、逐行执行,开发体验跟浏览器调试前端代码一样流畅。
配置调试环境:
- 在VS Code里打开项目文件夹。
- 点击左侧边栏的“运行和调试”图标(那个播放按钮加小虫子的图标)。
- 点击“创建launch.json文件”,选择“Node.js”环境。
- VS Code会自动生成一个
.vscode/launch.json,默认配置即可使用:按下F5启动调试,会以调试模式运行当前入口文件。
如果你用的是nodemon,调试配置需要稍作调整,让VS Code通过nodemon启动:
json复制{
"version": "0.2.0",
"configurations": [
{
"name": "Launch via Nodemon",
"type": "node",
"request": "launch",
"runtimeExecutable": "nodemon",
"console": "integratedTerminal",
"runtimeArgs": ["--inspect"],
"program": "${workspaceFolder}/index.js",
"restart": true
}
]
}
配置好之后,在代码行号左侧点击一下,会出现一个红点,这就是断点。启动调试后,当请求经过断点所在行时,程序会暂停,左侧面板会显示当前作用域里的所有变量值。你可以按F10逐行执行,按F5继续到下一个断点。
调试能力是区分“会写代码”和“会排查代码”的分水岭。遇到Bug时,打断点看实际运行时的变量状态,比盯着代码猜要高效十倍。
5.3 环境变量管理:.env文件与dotenv
后端项目通常需要配置端口、数据库连接地址、密钥等信息。这些配置不适合硬编码在代码里,因为不同环境(本地、测试、生产)的配置值是不同的,而且密钥类信息也不该进版本控制。
Node.js本身支持从process.env读取环境变量,但你手动设置环境变量在Windows上比较麻烦(PowerShell的$env:PORT=3000),而且重启终端就失效了。更优雅的做法是用.env文件配合dotenv包。
安装:
bash复制npm install dotenv
在项目根目录创建.env文件:
env复制PORT=3000
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=yourpassword
在index.js的最顶部引入并配置:
javascript复制require('dotenv').config();
const app = require('./src/app');
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`);
});
这样process.env.PORT就能读到.env文件里的值了。注意dotenv一定要在引入其他模块之前调用,因为后续模块里可能会读取环境变量。
.env文件已经被我们在.gitignore里忽略了,所以你的密钥信息不会提交到Git仓库,这是正确的安全习惯。但同时,你应该提交一个.env.example文件,里面只写键名不写真实值,方便其他同事知道需要配置哪些变量。
6. Windows上经常踩的坑与排查技巧
6.1 端口被占用:EADDRINUSE报错
启动服务时最常见的报错之一:
text复制Error: listen EADDRINUSE: address already in use :::3000
这说明3000端口已经被其他进程占用了。解决方法:
bash复制# 查看3000端口被哪个进程占用
netstat -ano | findstr :3000
输出结果里最后一列是PID(进程ID),然后打开任务管理器,在“详细信息”标签页里找到这个PID对应的进程,结束它。或者用命令强制结束:
bash复制# 把 <PID> 替换成实际查到的值
taskkill /PID <PID> /F
如果这个进程是你之前没停干净的Node.js服务,也可以直接再执行一次taskkill /PID <PID> /F。
顺便提一句,在WSL或Linux上查端口用的是lsof -i :3000,别记混了。
6.2 路径分隔符:两个反斜杠的教训
Windows文件系统用反斜杠(\)作为路径分隔符,而Linux/macOS用正斜杠(/)。Node.js在Windows上会自动处理大部分路径问题,但在你手动拼接路径时就会踩坑。
比如你要读取config目录下的db.json文件,如果写成:
javascript复制const fs = require('fs');
const path = './config\db.json';
在Windows上能跑,但代码推到Linux服务器上就会报错。正确的做法是使用Node.js内置的path模块:
javascript复制const path = require('path');
const dbPath = path.join(__dirname, 'config', 'db.json');
path.join()会根据当前操作系统自动选择正确的分隔符,这样你的代码换到任何平台都能跑。
还有一个问题容易被忽视:path模块提供的path.join()和path.resolve()看着像,实际上有区别。path.join()只是把各段路径拼接规范化,而path.resolve()会最终解析成绝对路径。绝大多数场景下用path.join()就够了。
6.3 终端的编码问题:中文乱码
在Windows终端里跑Node.js,偶尔会看到输出的中文变成了乱码。主要有两个原因:
第一个原因是PowerShell(或旧的命令提示符)默认代码页可能不是UTF-8。解决办法是在当前终端执行:
bash复制chcp 65001
chcp 65001表示把代码页切换到UTF-8。不过这个设置只对当前终端窗口生效,关掉就失效了。想永久改变的话,可以修改Windows的“区域设置”里的“Beta版:使用Unicode UTF-8提供全球语言支持”,但这会影响到整个系统,不建议随便开。
第二个原因是Node.js对中文的处理。比如你通过res.end()直接返回中文文本,浏览器里显示乱码。解决方法是显式设置响应头编码:
javascript复制res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
如果你用Express,res.send()和res.json()默认就是UTF-8,很少出现乱码问题。
6.4 全局安装包后提示“不是内部或外部命令”
在Windows上全局安装某个npm包后(比如npm install -g nodemon),有时会提示找不到该命令。这是因为npm全局安装目录没有正确添加到系统PATH。
解决方法是先查看npm全局安装路径:
bash复制npm config get prefix
然后把这个路径(默认是C:\Users\你的用户名\AppData\Roaming\npm)加入系统环境变量PATH。操作步骤:右键“此电脑” → “属性” → “高级系统设置” → “环境变量” → 在“系统变量”里找到Path,把npm全局目录追加进去,保存后重新打开终端。
6.5 node_modules文件夹损坏或安装中断
Windows上偶尔会遇到node_modules损坏的情况,表现是安装新包时报各种奇怪错误。最有效的解决办法就是“删了重装”:
bash复制# 把整个依赖目录删掉,然后重新安装
rmdir /s /q node_modules
npm install
在PowerShell里,rmdir可能还需要加上/s参数,或者直接用:
powershell复制Remove-Item -Recurse -Force node_modules
删之前确认你在项目根目录,别把整个盘的文件误删了。
6.6 用Postman或VS Code Rest Client测试接口
写完接口后需要测试,除了curl之外,我推荐两个更友好的工具:
- Postman:功能全面,支持集合管理、环境变量、自动化测试,适合日常接口调试。
- VS Code插件Rest Client:在编辑器里直接写HTTP请求发送,优点是不用切换窗口,配置简单。
VSCode的Rest Client只需要创建一个.http文件,写入:
http复制### 获取用户列表
GET http://localhost:3000/api/users
### 新增用户
POST http://localhost:3000/api/users
Content-Type: application/json
{
"name": "David"
}
然后点击请求行上方的“Send Request”按钮,就能看到响应。这个方式适合模拟真实场景,而且.http文件可以提交到版本控制里,方便团队成员共享接口定义。
7. 生产环境部署前的最后几点提醒
项目开发完了,本地跑得顺畅,并不代表可以直接扔到服务器上。有几个基础但关键的点,在Windows上开发时需要提前做好心理建设。
第一,生产环境不要用nodemon。npm start脚本里的node index.js才是生产环境正确的启动方式。nodemon是开发辅助工具,它的自动重启机制在生产环境下是隐患。
第二,process.env.NODE_ENV这个环境变量,通常用来区分当前是开发环境还是生产环境。你可以这样设置:
bash复制# Windows PowerShell
$env:NODE_ENV="production"
# 或使用cross-env包在package.json脚本里统一设置
实际上在Windows的终端里设置环境变量不太统一,更常见的做法是安装cross-env来在package.json中跨平台设置:
bash复制npm install -D cross-env
然后:
json复制{
"scripts": {
"start": "cross-env NODE_ENV=production node index.js"
}
}
第三,反向代理。生产环境中,Node.js服务通常不会直接对公网开放80端口,而是放在Nginx等反向代理后面。Nginx负责处理静态资源、SSL证书、负载均衡,把动态请求转发给Node.js。这意味着你的Node.js服务监听3000端口就够了,不需要关心HTTPS证书配置,那些是Nginx的活。
第四,进程守护。生产环境里Node.js进程如果意外退出,需要有个工具自动拉起来。主流方案是PM2,它可以实现进程守护、日志管理、负载均衡等功能。但这是部署阶段的事,初学阶段了解一下即可,不必现在就上手。
从零到一的这条路,核心目标不是做一个多复杂的系统,而是理解从安装运行环境、初始化项目、写出接口、本地调试,到最终能部署的全流程。把这套流程走通一遍,后续再学数据库、鉴权、部署、容器化,就都是在已有的骨架上填充肉了。
