关于 monorepo-management
面向管理多包仓库的开发团队,提供 monorepo 结构、依赖、构建、测试及发布的规划指南,并介绍常见工具与实践。
主要功能
- 01规划 monorepo 包结构
- 02配置 pnpm、npm 或 Yarn 工作区
- 03使用 Turborepo、Nx 等构建系统
- 04管理共享依赖与配置
- 05通过 Changesets 进行版本发布
适用场景
- 01从多仓库迁移到 monorepo
- 02搭建新的 monorepo 项目
- 03优化构建与测试性能
- 04配置包版本管理和发布
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ wshobson/ agents --skill monorepo-management安装后在 Claude Code 中输入/monorepo-management确认已加载。
附带文件references/details.md
详细介绍
Monorepo 管理
构建高效、可扩展的 Monorepo,实现跨多个软件包和应用共享代码、统一工具配置并进行原子化变更。
何时使用此技能
- 搭建新的 Monorepo 项目
- 从多仓库迁移到 Monorepo
- 优化构建和测试性能
- 管理共享依赖
- 实施代码共享策略
- 为 Monorepo 配置 CI/CD
- 为软件包进行版本管理和发布
- 调试 Monorepo 特有问题
核心概念
1. 为什么选择 Monorepo?
优势:
- 共享代码和依赖
- 跨项目进行原子化提交
- 统一工具和标准
- 更轻松地重构
- 简化依赖管理
- 提高代码可见性
挑战:
- 大规模场景下的构建性能
- CI/CD 复杂性
- 访问控制
- Git 仓库体积庞大
2. Monorepo 工具
软件包管理器:
- pnpm workspaces(推荐)
- npm workspaces
- Yarn workspaces
构建系统:
- Turborepo(大多数场景下推荐)
- Nx(功能丰富,但较复杂)
- Lerna(较旧,处于维护模式)
Turborepo 设置
初始设置
# Create new monorepo
npx create-turbo@latest my-monorepo
cd my-monorepo
# Structure:
# apps/
# web/ - Next.js app
# docs/ - Documentation site
# packages/
# ui/ - Shared UI components
# config/ - Shared configurations
# tsconfig/ - Shared TypeScript configs
# turbo.json - Turborepo configuration
# package.json - Root package.json
配置
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"]
},
"lint": {
"outputs": []
},
"dev": {
"cache": false,
"persistent": true
},
"type-check": {
"dependsOn": ["^build"],
"outputs": []
}
}
}
// package.json (root)
{
"name": "my-monorepo",
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"test": "turbo run test",
"lint": "turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"clean": "turbo run clean && rm -rf node_modules"
},
"devDependencies": {
"turbo": "^2.0.0",
"prettier": "^3.0.0",
"typescript": "^5.0.0"
},
"packageManager": "[email protected]"
}
pnpm 只会从 pnpm-workspace.yaml 读取工作区软件包,因此需要在其中声明(参见 references/details.md)。Turborepo 2 将 pipeline 重命名为 tasks,并会拒绝仍使用 pipeline 的 turbo.json;运行 npx @turbo/codemod migrate 可升级 1.x 配置。
软件包结构
// packages/ui/package.json
{
"name": "@repo/ui",
"version": "0.0.0",
"private": true,
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./button": {
"import": "./dist/button.js",
"types": "./dist/button.d.ts"
}
},
"scripts": {
"build": "tsup src/index.ts --format esm,cjs --dts",
"dev": "tsup src/index.ts --format esm,cjs --dts --watch",
"lint": "eslint src/",
"type-check": "tsc --noEmit"
},
"devDependencies": {
"@repo/tsconfig": "workspace:*",
"tsup": "^7.0.0",
"typescript": "^5.0.0"
},
"dependencies": {
"react": "^18.2.0"
}
}
详细模式和完整示例
详细的模式文档位于 references/details.md。如果上面的导航层级无法满足需求,请阅读该文件。
最佳实践
- 版本统一:在工作区中锁定依赖版本
- 共享配置:集中管理 ESLint、TypeScript、Prettier 配置
- 依赖关系图:保持无环,避免循环依赖
- 有效利用缓存:正确配置输入和输出
- 类型安全:在前端和后端之间共享类型
- 测试策略:在软件包中运行单元测试,在应用中运行 E2E 测试
- 文档:为每个软件包提供 README
- 发布策略:使用 changesets 进行版本管理
常见陷阱
- 循环依赖:A 依赖 B,B 又依赖 A
- 幽灵依赖:使用未列在 package.json 中的依赖
- 缓存输入不正确:Turborepo 输入中缺少文件
- 过度共享:共享本应分开的代码
- 共享不足:在多个软件包中重复代码
- 大型 Monorepo:缺少合适的工具时,构建速度会变慢
发布软件包
# Using Changesets
pnpm add -Dw @changesets/cli
pnpm changeset init
# Create changeset
pnpm changeset
# Version packages
pnpm changeset version
# Publish
pnpm changeset publish
# .github/workflows/release.yml
- name: Create Release Pull Request or Publish
uses: changesets/action@v1
with:
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
评论
支持 Markdown