目录
[1. 工作区定义 pnpm-workspace.yaml](#1. 工作区定义 pnpm-workspace.yaml)
[2. 根目录 .npmrc (解决幽灵依赖)](#2. 根目录 .npmrc (解决幽灵依赖))
[3. 共享组件示例 packages/ui/src/Button.vue](#3. 共享组件示例 packages/ui/src/Button.vue)
[4. 工具库入口 packages/utils/src/index.ts](#4. 工具库入口 packages/utils/src/index.ts)
[在 admin 应用中引用共享组件 apps/admin/package.json](#在 admin 应用中引用共享组件 apps/admin/package.json)
[在 Vue 组件中使用 apps/admin/src/App.vue](#在 Vue 组件中使用 apps/admin/src/App.vue)
[根目录 package.json 配置](#根目录 package.json 配置)
Monorepo的定义:将多个相关项目放在同一个代码仓库中管理(与每个项目独立仓库的Multirepo相对)。 优势:共享代码(如工具函数、组件)、统一配置、简化依赖管理、提高协作效率、降低版本同步成本等。 实现工具:常用的有pnpm workspaces、yarn workspaces、lerna、Turborepo、Nx等。 典型项目结构:在根目录下,通常有多个子目录(如apps/存放应用,packages/存放共享包)。
项目结构设计
my-monorepo/
├── apps/ # 业务应用
│ ├── admin/ # 后台管理系统 (Vue3)
│ ├── web/ # 官网项目 (React)
│ └── mobile/ # 移动端应用 (Vite)
├── packages/ # 共享模块
│ ├── ui/ # UI组件库
│ ├── utils/ # 工具函数库
│ └── api/ # 接口封装层
├── .npmrc # pnpm配置
├── pnpm-workspace.yaml # 工作区定义
└── package.json # 根配置
核心配置实现
1. 工作区定义 pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
2. 根目录 .npmrc (解决幽灵依赖)
shamefully-hoist = true
strict-peer-dependencies = false
3. 共享组件示例 packages/ui/src/Button.vue
<template>
<button class="ui-button">
<slot />
</button>
</template>
<style scoped>
.ui-button {
padding: 8px 16px;
background: #42b883;
color: white;
}
</style>
4. 工具库入口 packages/utils/src/index.ts
// 日期格式化工具
export const formatDate = (date: Date) =>
date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
// 防抖函数
export const debounce = (fn: Function, delay = 300) => {
let timer: number;
return (...args: any[]) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
};
跨项目引用实现
在 admin 应用中引用共享组件 apps/admin/package.json
{
"dependencies": {
"@my-monorepo/ui": "workspace:*",
"@my-monorepo/utils": "workspace:*"
}
}
在 Vue 组件中使用 apps/admin/src/App.vue
<script setup>
import { UiButton } from '@my-monorepo/ui'
import { formatDate } from '@my-monorepo/utils'
const today = formatDate(new Date())
</script>
<template>
<UiButton>点击按钮</UiButton>
<p>当前日期: {{ today }}</p>
</template>
高效开发命令
根目录 package.json 配置
{
"scripts": {
// 安装所有依赖
"install": "pnpm install",
// 并行启动所有应用
"dev": "pnpm --parallel run dev",
// 仅构建变更模块 (需配合Turborepo)
"build": "turbo run build",
// 按需安装依赖
"add": "pnpm add -wD"
}
}
关键优势实现
-
依赖提速
-
node_modules统一提升至根目录,节省 **70%+** 磁盘空间du -sh node_modules # 查看大小
-
-
热更新联动
修改共享组件 → 所有依赖项目实时生效(无需重启)
-
统一构建优化
graph LR
A[代码变更] --> B{Turborepo 检测}
B -->|影响 packages/ui| C[仅构建 UI 库]
B -->|影响 apps/admin| D[仅构建 Admin 应用]
完整操作流程
# 1. 创建项目
mkdir my-monorepo && cd my-monorepo
pnpm init
# 2. 配置工作区
echo "packages:\n - 'apps/*'\n - 'packages/*'" > pnpm-workspace.yaml
# 3. 创建子项目
mkdir -p apps/admin/{src,public} packages/ui/src
# 4. 安装共享依赖 (根目录)
pnpm add -wD vite typescript
# 5. 安装业务依赖 (admin项目)
pnpm --filter admin add vue@3
# 6. 启动开发
pnpm run dev
完整可运行项目模板:
monorepo-template
monorepo-pnpm-vue
实践建议
-
目录规范
apps/*存放业务应用packages/*存放可复用模块
-
版本控制
使用
changesets管理版本发布:pnpm add -wD @changesets/cli npx changeset init -
CI/CD 优化
配置 TurboRepo 缓存加速构建:
# .github/workflows/ci.yml - name: Restore turbo cache uses: actions/cache@v3 with: path: .turbo key: turbo-${{ hashFiles('**/package.json') }}