共计 2130 个字符,预计需要花费 6 分钟才能阅读完成。
开篇:全栈开发的三大痛点
作为全栈开发者,我们经常陷入这样的困境:

- 技术栈切换成本高:前后端使用不同语言开发,思维频繁切换导致效率低下
- API 契约管理混乱:接口文档与实现不同步,联调时才发现字段类型不匹配
- 部署流程复杂化:前端静态资源与后端服务需要独立部署,版本难以同步
技术方案设计
1. 前后端类型共享实践
通过 TypeScript 的类型定义实现前后端代码联动(示例使用 Express+React):
// shared/types/user.ts
export interface User {
id: string
name: string
email: string
createdAt: Date
}
// server/routes/users.ts
import {User} from '../../shared/types/user'
app.get('/api/users', (req, res) => {const users: User[] = await userService.findAll()
res.json(users)
})
// client/src/api/users.ts
import {User} from '../../shared/types/user'
const fetchUsers = async (): Promise<User[]> => {const res = await fetch('/api/users')
return res.json()}
2. Monorepo 架构设计
采用 Nx 或 Turborepo 搭建模块化工作区:
project-root
├── apps
│ ├── web # 前端应用
│ └── server # 后端服务
├── libs
│ ├── shared # 公共类型 / 工具
│ └── database # 数据访问层
└── package.json
3. 自动化 API 文档生成
使用 tsoa+Swagger 实现文档自动化:
// server/controllers/users.ts
import {Route, Get, Query} from 'tsoa'
@Route('users')
export class UsersController {@Get()
public async getUsers(@Query() page: number = 1
): Promise<User[]> {// 实现逻辑}
}
执行 tsoa spec-and-routes 即可生成 OpenAPI 规范文件。
性能优化实战
服务端渲染性能对比
| 方案 | TTFB | 首屏时间 | 缓存友好度 |
|---|---|---|---|
| CSR | 200ms | 800ms | ❌ |
| SSR | 300ms | 400ms | ✔️ |
| SSG | 50ms | 100ms | ✔️✔️ |
数据库连接池配置
// 使用 pg-pool 配置 PostgreSQL 连接池
const pool = new Pool({
max: 20, // 最大连接数
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
allowExitOnIdle: true
})
避坑指南
JWT 安全存储方案
- 前端:使用 HttpOnly + Secure 的 Cookie 存储
- 服务端:设置合理的 expiresIn(建议≤4 小时)
- 敏感操作:强制二次认证
跨服务事务实现
使用 Saga 模式保证最终一致性:
- 创建订单服务发起事务
- 库存服务预留商品
- 支付服务处理扣款
- 任一失败时触发补偿操作
容器内存限制
# docker-compose.yml 示例
services:
app:
image: my-app
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
完整代码示例
后端 API 路由
// server/routes/todos.ts
router.post('/todos',
validateBody(TodoSchema), // 使用 Zod 校验
async (req, res, next) => {
try {const todo = await todoService.create(req.body)
res.status(201).json(todo)
} catch (err) {next(new HttpError(500, '创建失败'))
}
}
)
前端数据层封装
// client/src/lib/api.ts
export async function fetchApi<T>(
path: string,
options?: RequestInit
): Promise<T> {const res = await fetch(`/api${path}`, {headers: { 'Content-Type': 'application/json'},
...options
})
if (!res.ok) {throw new Error(await res.text())
}
return res.json() as Promise<T>}
// 使用示例
const todos = await fetchApi<Todo[]>('/todos')
结语:微服务时代的全栈思考
当系统演进到微服务架构时,我们面临新的选择:
- 是否所有服务都应该使用相同技术栈?
- GraphQL 能否替代 REST 作为统一接口层?
- 如何在前端聚合不同服务的类型定义?
这需要我们在开发效率与技术多样性之间找到平衡点。你的解决方案是什么?欢迎在评论区分享实践心得。
正文完
发表至: 全栈开发
近一天内
