安装配置
本章节介绍 Express.js 的环境搭建、项目初始化以及开发工具配置。
环境要求
Express 5.x 对 Node.js 版本有明确要求:
| Express 版本 | Node.js 版本要求 |
|---|---|
| 5.x | >= 18.0.0 |
| 4.x | >= 0.10.0 |
推荐使用 Node.js 20 LTS 版本,这是目前的长期支持版本,稳定性和性能都有保障。
其他要求:
- npm: 9.x 或更高版本(随 Node.js 安装)
- 代码编辑器: VS Code(推荐)
检查环境
# 检查 Node.js 版本
node --version
# 应该输出 v20.x.x 或更高
# 检查 npm 版本
npm --version
# 查看 Node.js 安装路径
which node # macOS/Linux
where node # Windows
项目初始化
方式一:手动创建(推荐)
手动创建项目可以更好地理解项目结构和配置:
# 创建项目目录
mkdir my-express-app
cd my-express-app
# 初始化 package.json
npm init -y
# 安装 Express 5.x
npm install express@5
# 安装常用依赖
npm install dotenv helmet cors morgan
# 安装开发依赖
npm install -D nodemon
安装完成后检查版本:
npm list express
# [email protected]
# └── [email protected]
方式二:使用 Express 生成器
Express 生成器可以快速创建项目骨架:
# 安装生成器(全局安装)
npm install -g express-generator
# 创建项目(支持多种模板引擎)
express my-express-app # 默认 Jade 模板
express --view=ejs my-express-app # 使用 EJS 模板
express --view=pug my-express-app # 使用 Pug 模板
express --view=hbs my-express-app # 使用 Handlebars 模板
# 进入项目并安装依赖
cd my-express-app
npm install
生成器创建的项目结构:
my-express-app/
├── bin/
│ └── www # 启动脚本
├── public/ # 静态文件
│ ├── images/
│ ├── javascripts/
│ └── stylesheets/
├── routes/ # 路由
│ ├── index.js
│ └── users.js
├── views/ # 视图模板
│ ├── error.jade
│ ├── index.jade
│ └── layout.jade
├── app.js # 应用配置
└── package.json
项目结构
MVC 结构(推荐)
对于中大型项目,推荐使用 MVC 结构:
my-express-app/
├── src/
│ ├── config/ # 配置文件
│ │ ├── database.js # 数据库配置
│ │ ├── index.js # 配置入口
│ │ └── redis.js # Redis 配置
│ ├── controllers/ # 控制器
│ │ ├── authController.js
│ │ └── userController.js
│ ├── middleware/ # 中间件
│ │ ├── auth.js
│ │ ├── errorHandler.js
│ │ └── validate.js
│ ├── models/ # 数据模型
│ │ ├── User.js
│ │ └── Post.js
│ ├── routes/ # 路由定义
│ │ ├── index.js # 路由入口
│ │ ├── auth.js
│ │ └── users.js
│ ├── services/ # 业务逻辑
│ │ ├── authService.js
│ │ └── emailService.js
│ ├── utils/ # 工具函数
│ │ ├── response.js
│ │ └── logger.js
│ ├── validators/ # 数据验证
│ │ └── userValidator.js
│ └── app.js # 应用入口
├── tests/ # 测试文件
│ ├── unit/
│ └── integration/
├── public/ # 静态文件
├── logs/ # 日志文件
├── .env # 环境变量
├── .env.example # 环境变量示例
├── .gitignore
├── package.json
└── README.md
小型项目结构
对于小型项目或 API 服务:
my-api/
├── src/
│ ├── routes/ # 路由
│ ├── middleware/ # 中间件
│ └── app.js # 入口
├── tests/
├── .env
└── package.json
基础配置
package.json 配置
{
"name": "my-express-app",
"version": "1.0.0",
"description": "Express.js application",
"main": "src/app.js",
"scripts": {
"start": "node src/app.js",
"dev": "nodemon src/app.js",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix"
},
"keywords": ["express", "nodejs", "api"],
"author": "",
"license": "MIT",
"dependencies": {
"express": "^5.0.0"
},
"devDependencies": {
"nodemon": "^3.0.0"
},
"engines": {
"node": ">=18.0.0"
}
}
环境变量管理
安装 dotenv:
npm install dotenv
创建 .env 文件:
# 应用配置
NODE_ENV=development
PORT=3000
# 数据库
MONGODB_URI=mongodb://localhost:27017/myapp
# Redis
REDIS_URL=redis://localhost:6379
# 安全
JWT_SECRET=your-super-secret-key-at-least-32-characters
JWT_EXPIRES_IN=7d
# 日志
LOG_LEVEL=debug
创建 .env.example 作为模板:
# 应用配置
NODE_ENV=development
PORT=3000
# 数据库
MONGODB_URI=
# Redis
REDIS_URL=
# 安全
JWT_SECRET=
JWT_EXPIRES_IN=7d
# 日志
LOG_LEVEL=debug
使用环境变量:
// src/app.js
require('dotenv').config();
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`);
});
.gitignore 配置
# 依赖
node_modules/
# 环境变量
.env
.env.local
.env.*.local
# 日志
logs/
*.log
npm-debug.log*
# 构建输出
dist/
build/
# IDE
.idea/
.vscode/
*.swp
*.swo
# 操作系统
.DS_Store
Thumbs.db
# 测试
coverage/
# 临时文件
tmp/
temp/
开发工具配置
Nodemon 热重载
Nodemon 监听文件变化自动重启服务:
npm install -D nodemon
创建 nodemon.json 配置文件:
{
"watch": ["src/"],
"ignore": ["src/**/*.test.js", "tests/"],
"ext": "js,json",
"exec": "node src/app.js",
"env": {
"NODE_ENV": "development"
}
}
ESLint 代码检查
npm install -D eslint @eslint/js
npx eslint --init
eslint.config.js 配置(ESLint 9.x 扁平配置):
const js = require('@eslint/js');
module.exports = [
js.configs.recommended,
{
languageOptions: {
ecmaVersion: 2022,
sourceType: 'commonjs'
},
rules: {
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'no-console': 'off',
'semi': ['error', 'always'],
'quotes': ['error', 'single']
}
},
{
ignores: ['node_modules/', 'dist/', 'coverage/']
}
];
Prettier 代码格式化
npm install -D prettier eslint-config-prettier
.prettierrc 配置:
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 100
}
VS Code 配置
创建 .vscode/settings.json:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"javascript.preferences.importModuleSpecifier": "relative",
"typescript.preferences.importModuleSpecifier": "relative"
}
创建 .vscode/launch.json 用于调试:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/src/app.js",
"envFile": "${workspaceFolder}/.env"
},
{
"type": "node",
"request": "launch",
"name": "Jest: Current File",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": ["${fileBasenameNoExtension}", "--config", "jest.config.js"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"windows": {
"program": "${workspaceFolder}/node_modules/jest/bin/jest"
}
}
]
}
TypeScript 支持
安装 TypeScript
npm install -D typescript @types/express @types/node
npx tsc --init
tsconfig.json 配置
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"moduleResolution": "node",
"baseUrl": "./src",
"paths": {
"@/*": ["./*"],
"@routes/*": ["routes/*"],
"@controllers/*": ["controllers/*"],
"@middleware/*": ["middleware/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
TypeScript 示例
// src/app.ts
import express, { Application, Request, Response, NextFunction, Router } from 'express';
import helmet from 'helmet';
import cors from 'cors';
const app: Application = express();
// 中间件
app.use(helmet());
app.use(cors());
app.use(express.json());
// 定义路由类型
interface UserParams {
id: string;
}
interface UserBody {
name: string;
email: string;
}
// 路由
app.get('/', (req: Request, res: Response) => {
res.json({ message: 'Hello Express with TypeScript!' });
});
app.get('/users/:id', (req: Request<UserParams>, res: Response) => {
const { id } = req.params;
res.json({ id, name: 'User ' + id });
});
app.post('/users', (req: Request<{}, {}, UserBody>, res: Response) => {
const { name, email } = req.body;
res.status(201).json({ name, email });
});
// 错误处理中间件
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error(err.stack);
res.status(500).json({ error: 'Internal Server Error' });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
export default app;
package.json 脚本更新
{
"scripts": {
"build": "tsc",
"start": "node dist/app.js",
"dev": "ts-node-dev --respawn src/app.ts"
},
"devDependencies": {
"ts-node-dev": "^2.0.0",
"typescript": "^5.0.0"
}
}
ES Module 支持
Node.js 原生支持 ES Module,Express 5.x 完全兼容。
启用 ES Module
在 package.json 中添加:
{
"type": "module"
}
ES Module 语法
// src/app.js
import express from 'express';
import helmet from 'helmet';
import cors from 'cors';
const app = express();
app.use(helmet());
app.use(cors());
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'Hello ES Module!' });
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
export default app;
// src/routes/users.js
import { Router } from 'express';
const router = Router();
router.get('/', (req, res) => {
res.json({ users: [] });
});
export default router;
注意:ES Module 中 __dirname 和 __filename 不可用,需要使用替代方案:
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// 使用
app.use(express.static(join(__dirname, 'public')));
调试技巧
使用 Node.js 调试器
# 启动调试模式
node --inspect src/app.js
# 等待调试器连接
node --inspect-brk src/app.js
然后在 Chrome DevTools 中打开 chrome://inspect。
使用 console 调试
// 查看完整对象
console.log(JSON.stringify(obj, null, 2));
// 带时间戳的日志
console.log(`[${new Date().toISOString()}] ${message}`);
// 使用 console.table 查看数组
console.table(users, ['id', 'name', 'email']);
使用 debug 模块
npm install debug
const debug = require('debug')('app:routes');
debug('用户请求: %O', req.body);
运行时设置环境变量:
DEBUG=app:* node src/app.js
DEBUG=app:routes,app:middleware node src/app.js
常见问题
1. 端口被占用
# 查找占用端口的进程
lsof -i :3000 # macOS/Linux
netstat -ano | findstr :3000 # Windows
# 终止进程
kill -9 <PID> # macOS/Linux
taskkill /PID <PID> /F # Windows
2. 模块找不到
确保模块已安装,检查导入路径是否正确:
// 检查模块是否安装
npm list express
// 清除缓存重新安装
rm -rf node_modules package-lock.json
npm install
3. 环境变量不生效
确保 .env 文件在项目根目录,且在入口文件最顶部加载:
// 必须在最顶部
require('dotenv').config();
// 之后才能使用 process.env
const express = require('express');
4. Express 5 兼容性问题
某些中间件可能还未完全兼容 Express 5,检查更新或寻找替代方案:
# 检查过期依赖
npm outdated
# 更新依赖
npm update
小结
本章介绍了 Express.js 开发环境的搭建:
- 环境要求:Node.js 18+,推荐 20 LTS
- 项目初始化:手动创建或使用生成器
- 项目结构:MVC 结构适合中大型项目
- 基础配置:package.json、环境变量、.gitignore
- 开发工具:Nodemon、ESLint、Prettier、VS Code
- TypeScript:完整的类型支持
- ES Module:现代 JavaScript 模块语法
- 调试技巧:调试器、日志、debug 模块
- 常见问题:端口占用、模块查找、环境变量
良好的开发环境配置是高效开发的基础,建议根据项目需求选择合适的工具和配置。
练习
- 创建一个新的 Express 项目,配置完整的开发环境
- 为项目添加 TypeScript 支持,并实现一个简单的用户 API
- 配置 ESLint 和 Prettier,确保代码风格一致
- 使用 VS Code 调试功能,设置断点调试 Express 应用
- 将项目从 CommonJS 迁移到 ES Module