字
字节笔记本
2026年7月20日
Monorepo 最佳实践:从前端到全栈的仓库管理方案
API中转
¥120
Monorepo 最佳实践:从前端到全栈的仓库管理方案
Monorepo(单仓库多项目)把多个相关项目放在同一个 Git 仓库中管理。本文介绍 Monorepo 的适用场景、工具选型,以及前端和全栈项目的目录结构设计。
什么时候该用 Monorepo
适合 Monorepo 的典型场景:
- 多端前端:小程序 + H5 + 管理后台共享组件和工具函数
- 前后端一体:前端项目 + 后端 API 共享类型定义和配置
- 微服务集群:多个 Go/Node 服务共享公共库
- 开源项目:核心库 + 示例 + 文档在同一仓库
不适合的场景:
- 各项目之间没有代码共享
- 团队成员只负责各自项目,没有协作需求
- 构建时间已经成为瓶颈
前端 Monorepo:pnpm + Turborepo
目录结构
text
my-monorepo/
├── pnpm-workspace.yaml # workspace 配置
├── turbo.json # Turborepo 构建配置
├── package.json # 根 package.json
├── packages/
│ ├── shared/ # 共享包
│ │ ├── src/
│ │ │ ├── request.ts # 封装的请求工具
│ │ │ ├── storage.ts # 本地存储封装
│ │ │ └── types.ts # 共享类型定义
│ │ └── package.json
│ ├── miniapp/ # 小程序项目
│ │ ├── src/
│ │ └── package.json
│ └── admin/ # 管理后台
│ ├── src/
│ └── package.json
└── tsconfig.jsonpnpm workspace 配置
yaml
# pnpm-workspace.yaml
packages:
- 'packages/*'根 package.json
json
{
"name": "my-monorepo",
"private": true,
"scripts": {
"dev": "turbo run dev",
"build": "turbo run build",
"lint": "turbo run lint",
"test": "turbo run test"
},
"devDependencies": {
"turbo": "^1.10.0",
"typescript": "^5.3.0"
}
}turbo.json 构建配置
json
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {},
"test": {
"dependsOn": ["build"]
}
}
}dependsOn: ["^build"] 表示当前包的 build 依赖所有上游包的 build 先完成。Turborepo 会根据依赖图自动确定执行顺序,并缓存构建结果。
子项目引用共享包
json
// packages/miniapp/package.json
{
"dependencies": {
"@proj/shared": "workspace:*"
}
}workspace:* 表示使用 workspace 内的最新版本,pnpm 会自动创建软链接。
共享工具示例
typescript
// packages/shared/src/request.ts
interface ApiResponse<T> {
code: number
data: T
message: string
}
export async function request<T>(url: string, options?: RequestInit): Promise<T> {
const response = await fetch(url, {
headers: { 'Content-Type': 'application/json', ...options?.headers },
...options,
})
const result: ApiResponse<T> = await response.json()
if (result.code !== 0) throw new Error(result.message)
return result.data
}
// packages/shared/src/storage.ts
const isPlatform = () => {
if (typeof wx !== 'undefined') return 'wx'
if (typeof window !== 'undefined') return 'web'
return 'node'
}
export const storage = {
get(key: string) {
const platform = isPlatform()
if (platform === 'wx') return wx.getStorageSync(key)
return localStorage.getItem(key)
},
set(key: string, value: string) {
const platform = isPlatform()
if (platform === 'wx') return wx.setStorageSync(key, value)
return localStorage.setItem(key, value)
}
}通过平台判断,同一套代码可以在小程序和 Web 中复用。
全栈 Monorepo:前端 + Go 后端
当项目同时包含前端和后端时,可以用 pnpm 管理前端,Go modules 管理后端。
目录结构
text
my-project/
├── packages/
│ ├── shared/ # 前端共享包
│ ├── miniapp/ # 小程序
│ └── admin/ # 管理后台(Vue3)
├── server/ # Go 后端
│ ├── cmd/
│ │ └── main.go # 入口
│ ├── internal/ # 内部包(不对外暴露)
│ ├── pkg/ # 可复用的公共包
│ └── go.mod
├── pnpm-workspace.yaml
├── turbo.json
└── docker-compose.yml # 本地开发环境(MySQL 等)pnpm-workspace.yaml 排除 Go 后端目录:
yaml
packages:
- 'packages/*'
- '!packages/server'docker-compose.yml
yaml
version: '3'
services:
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: myapp
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:版本管理:Changesets
当 monorepo 中的包需要独立发版时,用 Changesets 管理版本号和 CHANGELOG。
bash
# 安装
pnpm add -Dw @changesets/cli
# 初始化
npx changeset init
# 记录变更
npx changeset
# 交互式选择:哪些包有变更、语义化版本级别(patch/minor/major)
# 版本升级
npx changeset version
# 发布
npx changeset publishMonorepo vs 多仓库对比
| 维度 | Monorepo | 多仓库(Multirepo) |
|---|---|---|
| 代码共享 | 天然方便,直接 import | 需要发包或 Git Submodule |
| 版本管理 | Changesets 自动关联 | 各仓库独立管理 |
| CI/CD | 需要增量构建(Turborepo 缓存) | 简单直接 |
| 权限控制 | 全仓库统一权限 | 可以按仓库分别授权 |
| 代码审查 | 可以跨项目审查 | 独立审查 |
| 初期搭建 | 需要配置工具链 | 零配置 |
| 仓库体积 | 较大 | 各仓库独立 |
常用工具对比
| 工具 | 语言生态 | 特点 |
|---|---|---|
| Turborepo | JS/TS | 增量构建、远程缓存、配置简单 |
| Nx | JS/TS | 功能最全、插件丰富、学习曲线陡 |
| Lerna | JS/TS | 老牌工具、社区大、配置灵活 |
| pnpm workspace | JS/TS | 包管理器原生支持,通常与 Turbo/Nx 搭配 |
| Go workspace | Go | Go 1.18+ 原生多模块支持 |
| Bazel | 多语言 | Google 出品、功能强大、配置复杂 |
对于中小型项目,pnpm + Turborepo 是最实用的组合。大型团队或企业级项目可以考虑 Nx。
总结
Monorepo 的核心价值在于代码共享和统一管理。pnpm workspace 解决包管理问题,Turborepo 解决构建效率问题,Changesets 解决版本管理问题。对于前后端一体的项目,pnpm 管前端、Go modules 管后端、docker-compose 管基础设施,可以组成一套完整的开发工作流。
分享: