跳到主要内容

安装配置

本章节介绍 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 开发环境的搭建:

  1. 环境要求:Node.js 18+,推荐 20 LTS
  2. 项目初始化:手动创建或使用生成器
  3. 项目结构:MVC 结构适合中大型项目
  4. 基础配置:package.json、环境变量、.gitignore
  5. 开发工具:Nodemon、ESLint、Prettier、VS Code
  6. TypeScript:完整的类型支持
  7. ES Module:现代 JavaScript 模块语法
  8. 调试技巧:调试器、日志、debug 模块
  9. 常见问题:端口占用、模块查找、环境变量

良好的开发环境配置是高效开发的基础,建议根据项目需求选择合适的工具和配置。

练习

  1. 创建一个新的 Express 项目,配置完整的开发环境
  2. 为项目添加 TypeScript 支持,并实现一个简单的用户 API
  3. 配置 ESLint 和 Prettier,确保代码风格一致
  4. 使用 VS Code 调试功能,设置断点调试 Express 应用
  5. 将项目从 CommonJS 迁移到 ES Module