01-Node.js环境搭建
Node.js是基于Chrome V8引擎的JavaScript运行时,2009年由Ryan Dahl创建。事件驱动、非阻塞I/O,适合高并发场景。
Node.js简介
设计特点
事件驱动:基于事件循环处理I/O
非阻塞I/O:异步操作,高并发
单线程:主线程单一,Worker Threads可多线程
V8引擎:JIT编译,性能优秀
跨平台:Linux/Windows/macOS
应用场景
Web后端:
RESTful API服务
微服务架构
实时应用(聊天、协作)
BFF(Backend For Frontend)
工具链:
Webpack、Vite构建工具
ESLint、Prettier代码工具
npm、yarn包管理
桌面应用:
Electron(VS Code、Slack)
其他:
服务端渲染(Next.js、Nuxt.js)
Serverless函数
IoT设备
技术优势
优势:
JavaScript全栈开发
npm生态丰富(200万+包)
异步I/O高并发
快速开发迭代
活跃社区
劣势:
CPU密集型任务性能差
回调地狱(已被Promise/async解决)
单线程限制(Worker Threads补充)
类型安全弱(TypeScript补充)
环境安装
版本选择
# 查看版本
node --version
npm --version
# LTS版本(推荐生产环境)
# Node.js 18 LTS(2022-10到2025-04)
# Node.js 20 LTS(2023-10到2026-04)
# Current版本(最新特性)
# Node.js 21(2023-10发布)
安装方式
1. 官方安装包
# 下载:https://nodejs.org
# LTS: 稳定版
# Current: 最新版
# 验证
node -v
npm -v
2. nvm(推荐)
# 安装nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# macOS
brew install nvm
# 安装Node.js
nvm install 18 # 安装v18
nvm install 20 # 安装v20
nvm install --lts # 安装最新LTS
# 切换版本
nvm use 18
nvm use 20
# 设置默认版本
nvm alias default 18
# 查看已安装版本
nvm list
# 查看可用版本
nvm list-remote
3. 包管理器
# Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# macOS
brew install node@18
# Windows
choco install nodejs-lts
npm包管理
基本命令
# 初始化项目
npm init
npm init -y # 默认配置
# 安装依赖
npm install express # 生产依赖
npm install -D jest # 开发依赖
npm install -g nodemon # 全局安装
# 简写
npm i express
npm i -D jest
npm i -g nodemon
# 安装特定版本
npm install express@4.18.0
npm install express@latest
# 卸载
npm uninstall express
npm uninstall -g nodemon
# 更新
npm update
npm update express
# 查看过期包
npm outdated
# 审计安全漏洞
npm audit
npm audit fix
# 查看依赖树
npm list
npm list --depth=0
# 清理缓存
npm cache clean --force
package.json
{
"name": "myapp",
"version": "1.0.0",
"description": "My Node.js app",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"build": "webpack"
},
"keywords": ["api", "rest"],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"express": "^4.18.0",
"mongoose": "^7.0.0"
},
"devDependencies": {
"jest": "^29.0.0",
"nodemon": "^3.0.0"
},
"engines": {
"node": ">=18.0.0"
}
}
语义化版本
{
"dependencies": {
"express": "4.18.2", // 精确版本
"mongoose": "^7.0.0", // 兼容版本(7.x.x)
"axios": "~1.4.0", // 补丁版本(1.4.x)
"lodash": "*", // 任意版本(不推荐)
"dotenv": "latest" // 最新版本(不推荐)
}
}
模块系统
CommonJS(默认)
// 导出
// math.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
module.exports = { add, subtract };
// 或
exports.add = add;
exports.subtract = subtract;
// 导入
// main.js
const math = require('./math');
console.log(math.add(2, 3));
// 解构导入
const { add, subtract } = require('./math');
console.log(add(2, 3));
// 内置模块
const fs = require('fs');
const path = require('path');
const http = require('http');
ES Modules
// package.json
{
"type": "module"
}
// 导出
// math.mjs 或 math.js(如果package.json设置了"type": "module")
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// 默认导出
export default function multiply(a, b) {
return a * b;
}
// 导入
import { add, subtract } from './math.mjs';
import multiply from './math.mjs';
// 全部导入
import * as math from './math.mjs';
// 内置模块
import fs from 'fs';
import path from 'path';
开发工具
VS Code配置
必装插件:
ESLint
Prettier
JavaScript (ES6) code snippets
REST Client
npm Intellisense
配置(.vscode/settings.json):
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"eslint.validate": [
"javascript",
"javascriptreact"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
调试配置(.vscode/launch.json):
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/index.js"
},
{
"type": "node",
"request": "attach",
"name": "Attach",
"port": 9229
}
]
}
ESLint配置
# 安装
npm install -D eslint
# 初始化
npx eslint --init
# .eslintrc.json
{
"env": {
"node": true,
"es2021": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": "latest"
},
"rules": {
"indent": ["error", 2],
"quotes": ["error", "single"],
"semi": ["error", "always"]
}
}
Prettier配置
// .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80
}
Hello World
基本程序
// index.js
console.log('Hello, Node.js!');
# 运行
node index.js
HTTP服务器
// server.js
const http = require('http');
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
});
# 运行
node server.js
# 访问
curl http://localhost:3000
项目结构
标准布局
myproject/
├── package.json # 项目配置
├── package-lock.json # 依赖锁定
├── node_modules/ # 依赖包(.gitignore)
├── .env # 环境变量(.gitignore)
├── .gitignore
├── README.md
├── src/
│ ├── app.js # 应用入口
│ ├── routes/ # 路由
│ ├── controllers/ # 控制器
│ ├── models/ # 数据模型
│ ├── middlewares/ # 中间件
│ ├── services/ # 业务逻辑
│ ├── utils/ # 工具函数
│ └── config/ # 配置
├── tests/ # 测试
└── public/ # 静态文件
├── css/
├── js/
└── images/
常用内置模块
fs(文件系统)
const fs = require('fs');
// 同步读取
const data = fs.readFileSync('file.txt', 'utf8');
// 异步读取
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
// Promise版本
const fs = require('fs').promises;
async function readFile() {
try {
const data = await fs.readFile('file.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
}
// 写入
await fs.writeFile('output.txt', 'Hello');
// 追加
await fs.appendFile('log.txt', 'New line\n');
// 检查文件
if (fs.existsSync('file.txt')) {
console.log('文件存在');
}
// 目录操作
await fs.mkdir('newdir', { recursive: true });
await fs.rmdir('olddir');
await fs.readdir('dir');
path(路径)
const path = require('path');
// 拼接路径
const filePath = path.join(__dirname, 'public', 'index.html');
// 解析路径
path.dirname('/home/user/file.txt'); // '/home/user'
path.basename('/home/user/file.txt'); // 'file.txt'
path.extname('/home/user/file.txt'); // '.txt'
// 绝对路径
path.resolve('file.txt'); // '/current/dir/file.txt'
// 规范化
path.normalize('/foo/bar//baz/asdf/quux/..'); // '/foo/bar/baz/asdf'
process(进程)
// 环境变量
console.log(process.env.NODE_ENV);
console.log(process.env.PORT);
// 命令行参数
console.log(process.argv);
// node app.js arg1 arg2
// ['node', '/path/to/app.js', 'arg1', 'arg2']
// 当前目录
console.log(process.cwd());
// 进程ID
console.log(process.pid);
// 退出
process.exit(0); // 成功
process.exit(1); // 失败
// 监听退出
process.on('exit', (code) => {
console.log(`退出码: ${code}`);
});
// 监听未捕获异常
process.on('uncaughtException', (err) => {
console.error('未捕获异常:', err);
process.exit(1);
});
环境变量管理
dotenv
npm install dotenv
// .env文件
PORT=3000
DB_HOST=localhost
DB_USER=admin
DB_PASS=secret
NODE_ENV=development
// 加载
require('dotenv').config();
console.log(process.env.PORT); // '3000'
console.log(process.env.DB_HOST); // 'localhost'
// 不同环境
require('dotenv').config({
path: `.env.${process.env.NODE_ENV}`
});
调试
console调试
console.log('普通日志');
console.error('错误日志');
console.warn('警告日志');
console.info('信息日志');
console.table([{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }]);
console.time('操作');
// 耗时操作
console.timeEnd('操作'); // 操作: 123.456ms
console.trace('调用栈');
调试器
# Node.js内置调试器
node inspect index.js
# Chrome DevTools
node --inspect index.js
# 打开 chrome://inspect
# VS Code调试
# F5启动调试
# 断点、单步执行、变量查看
nodemon热重载
# 安装
npm install -D nodemon
# package.json
{
"scripts": {
"dev": "nodemon index.js"
}
}
# 运行
npm run dev
# nodemon.json配置
{
"watch": ["src"],
"ext": "js,json",
"ignore": ["node_modules", "tests"],
"exec": "node src/index.js"
}
性能监控
内置profiler
# CPU profile
node --prof app.js
# 生成报告
node --prof-process isolate-0x*.log > profile.txt
# 内存快照
node --heapsnapshot-signal=SIGUSR2 app.js
# 发送信号
kill -USR2 <pid>
clinic.js
# 安装
npm install -g clinic
# CPU分析
clinic doctor -- node app.js
# 火焰图
clinic flame -- node app.js
# 气泡图
clinic bubbleprof -- node app.js
包管理器对比
npm vs yarn vs pnpm
特性 |
npm |
yarn |
pnpm |
|---|---|---|---|
速度 |
中等 |
快 |
最快 |
磁盘占用 |
大 |
大 |
小(硬链接) |
lock文件 |
package-lock.json |
yarn.lock |
pnpm-lock.yaml |
离线缓存 |
有 |
有 |
有 |
Workspaces |
支持 |
支持 |
支持 |
yarn基本命令:
yarn init
yarn add express
yarn add -D jest
yarn remove express
yarn install
yarn upgrade
pnpm基本命令:
pnpm init
pnpm add express
pnpm add -D jest
pnpm remove express
pnpm install
pnpm update
项目配置
.gitignore
node_modules/
.env
.env.local
dist/
build/
*.log
.DS_Store
coverage/
.vscode/
.npmrc
registry=https://registry.npmmirror.com
save-exact=true
engine-strict=true
EditorConfig
# .editorconfig
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
核心: Node.js基于V8引擎和事件循环,非阻塞I/O实现高并发。npm生态丰富,工具链完善。