学完 JavaScript 语法,接下来要面对的就是"怎么运行它"。答案就是 Node.js:它让 JavaScript 跑在服务器上,同时带来了 npm 这个全球最大的软件包仓库。这篇文章从安装开始,带你走完"装环境、建项目、装依赖、写脚本、跑起来"的完整流程,最后亲手启动一个网页服务器,你会发现前端开发的世界一下子变大了。
1. 安装 Node.js:两种方式
Node.js 的安装有两种主流方式:直接去官网(nodejs.org)下载 LTS 版本安装包,一路下一步;或者用版本管理器 nvm 安装。推荐后者,因为前端项目经常需要不同版本的 Node,用 nvm 可以随时切换,不用反复重装系统级的软件。
# Windows 用户先装 nvm-windows(去官网下载安装包)
nvm install 20
nvm use 20
# 验证安装:下面两条命令都要有输出
node -v
npm -v
node -v 输出版本号说明 Node 本体装好了,npm -v 输出版本号说明包管理器也好了。注意 LTS 版本(如 20.x)是长期维护版,生产环境优先选它;奇数版本如 21、23 是新特性版,适合尝鲜,别用在正式项目里。
装好之后立刻做个小实验:新建一个 hello.js,写一行 console.log('hello node'),然后 node hello.js——看到输出,你的 Node 环境就正式可用了。如果后面遇到"找不到 node 命令",八成是安装时没把 Node 加进系统 PATH,重装时勾上 "Add to PATH" 选项即可。想确认全局包装在哪,执行 npm root -g,Windows 上通常在 AppData\Roaming\npm 目录下。
还有个容易忽略的概念:npm 本身也是 Node 程序,所以升级 Node 通常就带着升级了 npm;想单独升级 npm,执行 npm install -g npm@latest。装完环境后建议顺手执行一次 npm config get registry,如果输出的是国外官方源,在国内网络环境下可以把镜像源切到国内:npm config set registry https://registry.npmmirror.com——这一步能让你后续每次安装都快好几倍。
2. 用 npm init 创建项目
每个 Node 项目的根目录都有一个 package.json,它相当于项目的"身份证加购物清单":记录项目叫什么、依赖了哪些包、怎么启动。执行 npm init 它会一步步问你问题,嫌麻烦直接 npm init -y 用默认值生成。
mkdir my-first-app
cd my-first-app
npm init -y
生成后目录里多了一个 package.json,先别管里面的字段,继续往下走,装第一个依赖后你会立刻理解它的作用。
npm init -y 生成的默认值足够起步,但有两个细节值得改:把 author 填上自己的名字或 GitHub 用户名,把 license 改成 MIT(开源项目的通行协议)。以后每开一个新项目,npm init -y 加两行修改,十秒钟就能把"项目身份证"办好。想体验交互模式的话,去掉 -y 执行 npm init,每一步都有英文提示,拿不准就直接回车用默认值,最后会打印生成的配置让你确认。
3. 安装依赖:三种位置要分清
npm install 包名 是装依赖的通用命令,但"装到哪里"有三种情况,新手最容易混淆:
| 命令 | 位置 | 用途 |
|---|---|---|
| npm install express | dependencies | 运行时依赖,项目上线也要用 |
| npm install eslint --save-dev | devDependencies | 开发期依赖,打包上线不需要 |
| npm install -g nodemon | 全局 | 命令行工具,和具体项目无关 |
# 安装一个 Web 框架(写入 dependencies)
npm install express
# 安装代码检查工具(写入 devDependencies)
npm install eslint --save-dev
# 卸载依赖
npm uninstall eslint
# 查看当前项目装了哪些包
npm ls --depth=0
装完你会发现目录里多了 node_modules(所有依赖的实际文件,通常几千个,不要手动改)和 package-lock.json(锁定每个包的精确版本)。package-lock.json 一定要提交到 Git,它是"团队所有人装出一模一样依赖"的保证。
依赖多了以后,npm ls 还能帮你排查版本冲突:某个包依赖了另一个包的不同版本,npm 会把它并排列出并标出层级。日常维护还有两个命令:npm outdated 列出所有"有新版本"的包和当前版本、最新版本;npm audit 检查已安装依赖的安全漏洞,有漏洞时会给出修复建议,执行 npm audit fix 可以自动升级到安全版本。养成定期跑一次 npm audit 的习惯,比等出了安全事故再补救划算得多。
4. 读懂 package.json
装完依赖再回头看 package.json,字段就都认识了:
{
"name": "my-first-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"eslint": "^8.57.0"
}
}
重点是版本号前的符号:^4.18.2 表示"允许 4.x 的最新版"(不跨大版本),~4.18.2 表示"只允许 4.18.x 的小修",不带符号则是"锁死这个精确版本"。新手阶段记住:见到 ^ 是正常的,依赖更新交给 npm update 和 npm audit 处理即可。
name 和 version 是必填字段,name 只能用小写字母、数字、连字符和点,将来要发布到 npm 的话不能和别人重名。自己玩的项目建议加上 "private": true,防止手滑执行 npm publish 把代码发到公网。main 字段是"别人 require 这个包时,默认加载哪个文件",description 和 keywords 是发布时供搜索用的,个人项目可填可不填。
5. scripts:让 npm 替你跑命令
scripts 是 package.json 里最实用的字段:把常用的长命令起个短名字,npm run 名字 就能执行。约定俗成的名字有 start(启动项目)、test(跑测试)、dev(开发模式),其中 start 和 test 可以省略 run 直接写 npm start。
npm start # 启动项目(start 可省略 run)
npm run dev # 开发模式:文件一保存就自动重启
npm run lint # 跑代码检查
这些命令都定义在 scripts 字段里,见下面的 JSON。注意 npm run 有个隐藏福利:它会自动把 node_modules/.bin 加进 PATH,所以本地安装的 eslint、prettier 都能直接跑,不用写完整路径。
scripts 里的命令还能串联:比如 "deploy": "npm run lint && npm run build",用 && 保证 lint 通过才执行 build。配合 pre/post 前缀约定,npm test 之前会自动执行 pretest 里定义的任务——这是 npm 内置的生命周期钩子,理解了它,很多"自动化"其实只是几行 scripts。
"scripts": {
"start": "node server.js",
"dev": "node --watch server.js",
"lint": "eslint ."
}
node --watch 是 Node 18 以上自带的文件监听模式:代码一保存就自动重启,省去手动重启服务器的麻烦,相当于内置了 nodemon。团队协作时,把"怎么启动项目"写进 scripts,新同事 clone 下来执行 npm install && npm run dev 就能跑,不用看文档猜命令。
6. 实战:启动你的第一个 HTTP 服务器
纸上谈兵结束,现在写一个真正的服务器:新建 server.js,用 Node 自带模块启动,不装任何框架也能跑。然后执行 npm start,浏览器打开 http://localhost:3000 就能看到页面。
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end('<h1>你好,Node!</h1><p>第一个服务器启动成功</p>');
});
server.listen(3000, () => {
console.log('服务器已启动: http://localhost:3000');
});
http.createServer 接收一个回调,每次有请求进来就执行一次;req 是请求对象,res 是响应对象,res.end 把内容发回浏览器。listen(3000) 让服务器监听 3000 端口。按 Ctrl + C 可以停掉服务器——改完代码记得重启,或者用刚才配的 npm run dev 让它自动重启。
两个新手高频报错先预防一下:EADDRINUSE 表示 3000 端口已经被占用——要么换端口(listen(8080)),要么找到占用进程关掉;Ctrl + C 按了没反应时,多按几次或直接关掉终端窗口。另外 res.writeHead 里的 charset=utf-8 一定要写,否则浏览器会用默认编码解析,中文会变成乱码。想进一步区分不同路径,可以在回调里判断 req.url——这就是最朴素的"路由",也是练习题的起点。
7. 总结与练习
这一篇你完成了:安装 Node 与 npm、用 npm init 建项目、分清三类依赖、读懂 package.json 的版本号、用 scripts 固化命令、亲手写出并启动了一个 HTTP 服务器。接下来练三件事:
- 在
server.js里根据req.url返回不同内容:访问/显示首页,访问/about显示介绍页,其他路径返回 404。 - 用
npm install装一个你感兴趣的小工具包(比如chalk,给终端输出上色),写一段脚本调用它,体会"站在巨人的肩膀上"。 - 把项目推上 GitHub,在另一台电脑上
git clone后只执行npm install就能跑起来——这就是 package-lock.json 存在的意义。
💡 遇到报错先看最后几行,再搜关键词。npm install失败时,先试npm cache clean --force后重装,解决不了再去搜索引擎,大部分坑都有人踩过。