Monorepo(Monolithic Repository,单体仓库)是一种代码管理策略,核心是将一个项目的所有相关代码(包括多个应用、库、工具链等)集中存储在单个代码仓库中,而非按模块拆分到多个独立仓库(Multirepo)。
📑 目录
- 快速参考
- 什么是 Monorepo
- Monorepo vs Multirepo
- Monorepo 的优缺点
- 经典案例
- 何时使用 Monorepo
- 工具选型
- 工作区管理工具
- 任务调度工具
- 版本管理工具
- 代码质量工具
- 实战搭建
- 1. 初始化基础环境
- 2. 配置 pnpm 工作区
- 3. 配置 Turbo
- 4. 根目录 package.json 配置
- 5. 搭建核心包
- 6. 搭建文档站点
- 7. 搭建示例项目
- 8. 核心命令使用
- 9. 版本管理与发布
- 高级配置
- Turbo 缓存优化
- CI/CD 集成
- 依赖管理策略
- 最佳实践
- 常见问题
快速参考
工具选型速查表
| 工具类型 | 推荐工具 | 适用场景 | 备选方案 |
|---|---|---|---|
| 包管理器 | pnpm workspace | 磁盘效率高、安装速度快 | npm workspace、yarn workspace |
| 任务调度 | Turbo | 增量构建、并行任务、缓存 | Nx(企业级)、Rush(大型项目) |
| 版本管理 | Changeset | monorepo 友好的版本管理 | release-it(单包)、Lerna(传统) |
快速开始
1# 1. 初始化项目 2mkdir your-project && cd your-project 3pnpm init -y 4 5# 2. 安装 Turbo 6pnpm add turbo -D -w 7 8# 3. 配置工作区 9# 创建 pnpm-workspace.yaml 10 11# 4. 配置 Turbo 12# 创建 turbo.json 13 14# 5. 创建子包 15mkdir -p packages/core docs examples/basic 16
什么是 Monorepo
简单类比
- Multirepo:像多个独立的文件夹,每个项目 / 库单独存放(比如
react、react-dom、react-router各一个仓库) - Monorepo:像一个大文件夹,里面按功能分类存放所有相关项目(比如 Facebook 的
facebook/react仓库,包含 React 核心、文档、示例、相关工具等所有代码)
常用结构
1monorepo-root/ 2├── packages/ # 所有可复用包(库、工具) 3│ ├── utils/ # 通用工具库 4│ ├── components/ # UI 组件库 5│ └── cli/ # 命令行工具 6├── apps/ # 可部署应用 7│ ├── web/ # 网页应用 8│ └── admin/ # 管理后台 9├── scripts/ # 全局构建/测试脚本 10├── package.json # 根项目配置(依赖、脚本) 11└── pnpm-workspace.yaml # 工作区配置(pnpm 为例) 12
Monorepo vs Multirepo
| 对比维度 | Multirepo(多仓库) | Monorepo(单仓库) |
|---|---|---|
| 依赖管理 | 重复安装,版本不一致,易冲突 | 共享依赖,版本统一,减少冗余 |
| 跨项目引用 | 需发布 npm / 用相对路径,同步修改繁琐 | 本地直接引用,修改实时生效,无需发布 |
| 工程化规范 | 各仓库独立配置,维护成本高 | 根目录统一配置,所有子项目继承 |
| 代码复用 | 复制粘贴或发布私有包,复用成本高 | 仓库内直接复用,抽离库更便捷 |
| 版本管理与发布 | 手动协调多包版本(如 A 依赖 B,B 升级后 A 需手动更新) | 工具自动管理版本依赖(如 Changeset),批量发布 |
| 协作效率 | 跨仓库 PR 联动复杂,代码审查分散 | 所有代码在一个仓库,PR 集中,协作更高效 |
Monorepo 的优缺点
优点:
- ✅ 高效协作:所有代码集中管理,跨项目修改无需切换仓库,PR 集中审查
- ✅ 规范统一:工程化配置(lint、测试、构建)全局统一,降低维护成本
- ✅ 依赖优化:共享依赖减少安装体积,版本统一避免冲突
- ✅ 代码复用:子包间直接引用,无需发布,迭代速度快
缺点:
- ❌ 仓库体积增大:随着项目增多,仓库体积会变大,但现代 Git(如 Git LFS)可缓解
- ❌ 构建速度:大型 Monorepo 全量构建较慢,需借助 Turborepo 等工具实现增量构建和缓存
- ❌ 权限控制:难以对单个子包进行精细化权限控制(如需控制,可结合 Git 子模块或企业级工具如 GitLab Enterprise)
经典案例
前端 Monorepo 经典案例:
- React:
facebook/react仓库包含 React 核心、React DOM、React Server Components 等所有相关代码 - Vue:
vuejs/core仓库包含 Vue 3 核心、编译器、运行时等 - Vite:
vitejs/vite仓库包含 Vite 核心、官方插件(如@vitejs/plugin-react)等 - Tailwind CSS:
tailwindlabs/tailwindcss仓库包含核心库、CLI、插件等
何时使用 Monorepo
当你的项目满足以下 2 个及以上条件时,优先选择 Monorepo:
- ✅ 需拆分独立模块(核心包 + 文档 + 示例是典型场景)
- ✅ 模块间有依赖关系(如示例依赖核心包、文档引用核心包 API)
- ✅ 需统一构建、测试、发布流程
- ✅ 追求高效开发(增量构建、并行任务)
何时不使用 Monorepo:
- ❌ 单一核心包 + 简单 README 文档(单包架构足够)
- ❌ 子包之间完全独立,无依赖关系
- ❌ 团队规模小,维护成本高
工具选型
工作区管理工具
负责管理多包的依赖安装、路径映射、脚本执行,主流选择:
| 工具 | 磁盘效率 | 安装速度 | monorepo 支持 | 适用场景 |
|---|---|---|---|---|
| pnpm workspace | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 推荐,生态最优 |
| npm workspace | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | npm 7+ 原生支持 |
| yarn workspace | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | Yarn 1.x 传统方案 |
| Lerna | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | 早期方案,已过时 |
选型建议:
- 推荐:pnpm workspace(磁盘效率高、安装速度快、生态完善)
- 备选:npm workspace(npm 7+ 原生支持,无需额外配置)
核心特性:
- pnpm workspace:轻量、快速,原生支持 Monorepo,通过
pnpm-workspace.yaml配置子项目路径,自动处理包之间的软链接,安装依赖时复用缓存,效率极高 - Yarn Workspaces:与 pnpm 功能类似,支持
workspace:*语法声明内部依赖 - Lerna:早期流行的 Monorepo 工具,可搭配 npm/yarn 使用,擅长版本管理和发布,但依赖安装效率不如 pnpm
任务调度工具
需支持「多包构建」「增量构建」「依赖顺序构建」,避免每次全量构建:
| 工具 | 增量构建 | 并行任务 | 缓存机制 | 配置复杂度 | 适用场景 |
|---|---|---|---|---|---|
| Turbo | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 中小型项目(推荐) |
| Nx | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | 大型企业级项目 |
| Rush | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ | 超大型项目 |
选型建议:
- 中小型项目:Turbo(推荐,配置简单,性能优秀)
- 大型企业级项目:Nx(功能强大,但配置复杂)
- 超大型项目:Rush(微软开源,适合超大型 monorepo)
核心特性:
- Turbo:高性能构建系统,可缓存构建结果,并行执行任务(构建、测试、lint),大幅提升大型 Monorepo 的构建速度
- tsup:支持多入口、增量构建,适配 TypeScript 项目,可快速构建多个子包
- Rollup/Vite:适合构建库或应用,支持 Tree-shaking,Vite 还能提供开发时热更新
版本管理工具
解决多包版本联动、CHANGELOG 自动生成、npm 发布等问题:
| 工具 | monorepo 支持 | 多包版本同步 | 自动化程度 | 配置复杂度 | 适用场景 |
|---|---|---|---|---|---|
| Changeset | ⭐⭐⭐⭐⭐ | ✅ 自动同步 | ⭐⭐⭐ | ⭐⭐⭐ | 多包项目(推荐) |
| release-it | ⭐⭐⭐ | ❌ 需手动 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 单包项目、简单场景 |
| Lerna | ⭐⭐⭐ | ✅ 支持 | ⭐⭐⭐ | ⭐⭐ | 传统方案 |
选型建议:
- 多包项目、需要版本同步:Changeset(推荐)
- 单包项目、追求自动化:release-it
- 简单场景、快速发布:release-it
核心特性:
- Changeset:轻量、易用,支持按子包提交变更记录,自动计算版本号(语义化版本),生成 CHANGELOG,批量发布子包
- release-it:可搭配 Changeset 使用,提供交互式发布流程,支持 GitHub 标签、发布说明等
代码质量工具
统一管理 lint、测试、格式化:
| 工具类型 | 推荐工具 | 核心功能 |
|---|---|---|
| 代码规范 | ESLint + Prettier | 根目录配置,所有子项目共享规则,可通过 eslint-config-xxx 抽离自定义规则 |
| 测试框架 | Vitest / Jest | 统一测试框架,支持跨包测试,可在根目录运行所有子项目的测试用例 |
| Git Hooks | Husky + lint-staged | 提交代码前自动执行 lint 和测试,保障代码质量 |
实战搭建
以下是最简搭建流程,基于 pnpm(生态最优)+ Turbo + tsup(核心包打包)+ VitePress(文档)+ Vitest(测试)。
1. 初始化基础环境
1# 创建项目根目录 2mkdir your-project && cd your-project 3 4# 初始化根目录 package.json 5pnpm init -y 6 7# 安装 Turbo(任务调度) 8pnpm add turbo -D -w # -w 表示安装到根目录(workspace-root) 9
2. 配置 pnpm 工作区
创建 pnpm-workspace.yaml:
1# pnpm-workspace.yaml 2packages: 3 - 'packages/*' # 核心包(可发布) 4 - 'docs' # 文档站点(不发布) 5 - 'examples/*' # 示例项目(不发布) 6
3. 配置 Turbo
创建 turbo.json:
1{ 2 "$schema": "https://turbo.build/schema.json", 3 "globalDependencies": ["package.json", "turbo.json"], 4 "pipeline": { 5 "build": { 6 "dependsOn": ["^build"], 7 "outputs": [".next/**", "dist/**", "build/**", ".vitepress/dist/**"] 8 }, 9 "dev": { 10 "cache": false, 11 "persistent": true 12 }, 13 "test": { 14 "dependsOn": ["build"], 15 "outputs": ["coverage/**"] 16 }, 17 "lint": { 18 "outputs": [] 19 }, 20 "clean": { 21 "cache": false 22 } 23 } 24} 25
配置说明:
dependsOn: ["^build"]:构建前先构建依赖的子包outputs:指定构建输出目录,用于缓存判断cache: false:开发模式不缓存,避免热更新问题persistent: true:开发模式持续运行(如 watch 模式)
4. 根目录 package.json 配置
1{ 2 "name": "your-project-monorepo", 3 "version": "1.0.0", 4 "private": true, 5 "scripts": { 6 "build": "turbo run build", 7 "dev": "turbo run dev", 8 "test": "turbo run test", 9 "lint": "turbo run lint", 10 "clean": "turbo run clean && rm -rf node_modules", 11 "format": "prettier --write \"**/*.{ts,tsx,md,json}\"" 12 }, 13 "devDependencies": { 14 "turbo": "^2.0.0", 15 "prettier": "^3.0.0" 16 }, 17 "packageManager": "pnpm@9.0.0", 18 "engines": { 19 "node": ">=18.0.0", 20 "pnpm": ">=9.0.0" 21 } 22} 23
5. 搭建核心包
1# 创建核心包目录并初始化 2mkdir -p packages/core && cd packages/core 3pnpm init -y 4 5# 安装核心依赖(共享依赖安装到根目录) 6pnpm add -D tsup typescript vitest @types/node -w 7
核心包 package.json:
1{ 2 "name": "@your-org/core", 3 "version": "1.0.0", 4 "description": "核心功能包", 5 "type": "module", 6 "main": "./dist/index.cjs", 7 "module": "./dist/index.js", 8 "types": "./dist/index.d.ts", 9 "exports": { 10 ".": { 11 "import": "./dist/index.js", 12 "require": "./dist/index.cjs", 13 "types": "./dist/index.d.ts" 14 } 15 }, 16 "files": ["dist"], 17 "scripts": { 18 "build": "tsup", 19 "dev": "tsup --watch", 20 "test": "vitest run", 21 "test:watch": "vitest", 22 "lint": "eslint src/**/*.ts", 23 "clean": "rm -rf dist coverage" 24 }, 25 "keywords": ["core", "utils"], 26 "license": "MIT" 27} 28
核心包 tsup.config.ts:
1import { defineConfig } from 'tsup'; 2 3export default defineConfig({ 4 entry: ['src/index.ts'], 5 format: ['esm', 'cjs'], 6 dts: true, 7 clean: true, 8 sourcemap: true, 9 minify: true, 10 splitting: false, 11}); 12
核心包 src/index.ts:
1export const greet = (name: string) => { 2 return `Hello, ${name}!`; 3}; 4 5export const add = (a: number, b: number) => { 6 return a + b; 7}; 8
6. 搭建文档站点
1# 创建文档目录并初始化 2mkdir docs && cd docs 3pnpm init -y 4 5# 安装文档依赖 6pnpm add -D vitepress @vitepress/theme-default -w 7 8# 初始化 VitePress 文档 9npx vitepress init 10
文档 package.json:
1{ 2 "name": "@your-org/docs", 3 "version": "1.0.0", 4 "private": true, 5 "scripts": { 6 "dev": "vitepress dev", 7 "build": "vitepress build", 8 "preview": "vitepress preview", 9 "lint": "eslint . --ext .md,.ts", 10 "clean": "rm -rf .vitepress/dist" 11 }, 12 "dependencies": { 13 "@your-org/core": "workspace:*" 14 } 15} 16
在 Markdown 中可直接导入核心包,用于示例演示:
1# 快速使用 2 3```ts 4import { greet } from '@your-org/core'; 5 6console.log(greet('World')); // Hello, World!
### 7\. 搭建示例项目
```bash
# 创建示例目录并初始化
mkdir -p examples/basic && cd examples/basic
pnpm init -y
# 安装依赖(使用工作区协议引用核心包)
pnpm add @your-org/core@workspace:* -w
pnpm add -D vite @vitejs/plugin-react -w
示例 package.json:
1{ 2 "name": "@your-org/example-basic", 3 "version": "1.0.0", 4 "private": true, 5 "type": "module", 6 "scripts": { 7 "dev": "vite", 8 "build": "vite build", 9 "preview": "vite preview", 10 "clean": "rm -rf dist" 11 }, 12 "dependencies": { 13 "@your-org/core": "workspace:*" 14 } 15} 16
8. 核心命令使用
| 命令 | 作用 |
|---|---|
| pnpm run dev | 同时启动核心包监听、文档热更新、示例热更新 |
| pnpm run build | 一键构建核心包(ESM/CJS + 类型)、文档静态资源、示例 |
| pnpm run test | 运行所有子包的测试(核心包单元测试、示例冒烟测试) |
| pnpm run lint | 统一校验所有子包的代码规范 |
| pnpm run clean | 清理所有子包的构建产物和缓存 |
增量构建效果示例:
- 首次执行
pnpm run build:构建所有子包(core + docs + examples) - 修改核心包代码后再次执行
pnpm run build:仅重建 core 和依赖它的 examples,docs 未变更则直接复用缓存,构建速度提升 50%+
过滤特定子包执行任务:
1# 只构建核心包 2pnpm run build --filter=@your-org/core 3 4# 只构建文档和示例 5pnpm run build --filter=@your-org/docs --filter=@your-org/example-basic 6 7# 构建核心包及其依赖者 8pnpm run build --filter=@your-org/core... 9
9. 版本管理与发布
使用 Changeset(推荐,适合多包版本同步)
Changeset 完全支持 Turbo monorepo,可仅发布核心包(packages/core),文档和示例不发布,并支持多包版本同步:
优势:
- ✅ 专为 monorepo 设计,支持多包版本同步
- ✅ 自动更新依赖包的版本号
- ✅ 变更记录清晰,便于追溯
劣势:
- ❌ 需要手动记录变更(
npx changeset) - ❌ 流程相对复杂
安装与配置:
1# 安装 Changeset 并初始化 2pnpm add @changesets/cli -D -w 3npx changeset init 4
修改 Changeset 配置(.changeset/config.json):
1{ 2 "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", 3 "changelog": "@changesets/cli/changelog", 4 "commit": false, 5 "access": "public", 6 "baseBranch": "main", 7 "updateInternalDependencies": "patch", 8 "ignore": ["@your-org/docs", "@your-org/example-basic"] 9} 10
发布流程:
1# 1. 记录核心包变更(仅选择 @your-org/core) 2npx changeset 3 4# 2. 升级版本 + 生成 CHANGELOG 5npx changeset version 6 7# 3. 构建核心包 8pnpm run build --filter=@your-org/core 9 10# 4. 发布核心包 11pnpm publish --filter=@your-org/core --access public 12
使用 release-it(适合单包发布或简单场景)
release-it 也可以用于 monorepo,但主要用于单包发布场景。
优势:
- ✅ 自动化程度高,一条命令完成发布
- ✅ 配置灵活,支持自定义发布流程
- ✅ 支持 GitHub Release、npm 发布等
劣势:
- ❌ 不支持多包版本同步(需要手动处理)
- ❌ 需要为每个包单独配置或使用脚本
方式一:在子包中单独配置(推荐)
在需要发布的子包中配置 release-it:
1# 在核心包目录下 2cd packages/core 3pnpm add release-it @release-it/conventional-changelog -D 4
核心包 release-it.config.js:
1module.exports = { 2 git: { 3 commitMessage: 'chore: release @your-org/core@${version}', 4 tagName: '@your-org/core@${version}', 5 requireCleanWorkingDir: false, 6 requireBranch: 'main', 7 requireCommits: true, 8 }, 9 github: { 10 release: true, 11 releaseName: '@your-org/core@${version}', 12 }, 13 npm: { 14 publish: true, 15 publishPath: './', 16 }, 17 hooks: { 18 'before:init': ['pnpm run test'], 19 'after:bump': ['pnpm run build'], 20 'after:release': 'echo "Release @your-org/core@${version} completed!"', 21 }, 22 plugins: { 23 '@release-it/conventional-changelog': { 24 preset: 'angular', 25 infile: 'CHANGELOG.md', 26 }, 27 }, 28}; 29
核心包 package.json scripts:
1{ 2 "scripts": { 3 "release": "release-it", 4 "release:patch": "release-it patch", 5 "release:minor": "release-it minor", 6 "release:major": "release-it major" 7 } 8} 9
发布流程:
1# 在核心包目录下 2cd packages/core 3pnpm run release 4
方式二:在根目录统一配置(适合单包发布)
在根目录配置,配合 pnpm filter 使用:
1# 在根目录安装 2pnpm add release-it @release-it/conventional-changelog -D -w 3
根目录 release-it.config.js:
1module.exports = { 2 git: { 3 commitMessage: 'chore: release v${version}', 4 tagName: 'v${version}', 5 requireCleanWorkingDir: false, 6 requireBranch: 'main', 7 }, 8 hooks: { 9 'before:init': ['pnpm run test --filter=@your-org/core'], 10 'after:bump': ['pnpm run build --filter=@your-org/core'], 11 }, 12 plugins: { 13 '@release-it/conventional-changelog': { 14 preset: 'angular', 15 infile: 'CHANGELOG.md', 16 }, 17 }, 18}; 19
根目录 package.json scripts:
1{ 2 "scripts": { 3 "release": "release-it", 4 "release:core": "cd packages/core && pnpm run release" 5 } 6} 7
Changeset vs release-it 对比
| 特性 | Changeset | release-it |
|---|---|---|
| monorepo 支持 | ⭐⭐⭐⭐⭐(专为 monorepo 设计) | ⭐⭐⭐(需手动配置) |
| 多包版本同步 | ✅ 自动同步 | ❌ 需手动处理 |
| 自动化程度 | ⭐⭐⭐(需手动记录变更) | ⭐⭐⭐⭐⭐(一条命令) |
| 配置复杂度 | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| 适用场景 | 多包项目、版本同步需求 | 单包项目、简单场景 |
选型建议:
- 多包项目、需要版本同步:Changeset(推荐)
- 单包项目、追求自动化:release-it
- 简单场景、快速发布:release-it
高级配置
Turbo 缓存优化
1. 配置远程缓存(可选)
Turbo 支持远程缓存,团队共享构建缓存:
1# 安装 Turbo 远程缓存客户端 2pnpm add turbo -D -w 3 4# 登录 Vercel(免费提供远程缓存) 5npx turbo login 6 7# 链接项目 8npx turbo link 9
2. 优化缓存配置
1{ 2 "pipeline": { 3 "build": { 4 "dependsOn": ["^build"], 5 "outputs": ["dist/**"], 6 "env": ["NODE_ENV"], // 环境变量变化时重新构建 7 "inputs": ["src/**/*.ts", "tsup.config.ts"] // 指定输入文件 8 } 9 } 10} 11
CI/CD 集成
GitHub Actions 示例
创建 .github/workflows/ci.yml:
1name: CI 2 3on: 4 push: 5 branches: [main] 6 pull_request: 7 branches: [main] 8 9jobs: 10 build: 11 runs-on: ubuntu-latest 12 steps: 13 - uses: actions/checkout@v4 14 15 - uses: pnpm/action-setup@v4 16 with: 17 version: 9 18 19 - uses: actions/setup-node@v4 20 with: 21 node-version: 18 22 cache: 'pnpm' 23 24 - name: Install dependencies 25 run: pnpm install 26 27 - name: Build 28 run: pnpm run build 29 30 - name: Test 31 run: pnpm run test 32 33 - name: Lint 34 run: pnpm run lint 35
依赖管理策略
1. 公共依赖提升到根目录
1# 安装公共依赖到根目录 2pnpm add -D typescript eslint prettier -w 3 4# 子包无需重复安装,直接使用 5
2. 子包间依赖使用工作区协议
1{ 2 "dependencies": { 3 "@your-org/core": "workspace:*" // ✅ 正确 4 // "@your-org/core": "1.0.0" // ❌ 错误,无法实时同步 5 } 6} 7
3. 版本统一管理
使用 .npmrc 统一配置:
1# .npmrc 2shamefully-hoist=true 3strict-peer-dependencies=false 4
最佳实践
- 子包命名规范:使用 scope(如
@your-org/core),避免命名冲突 - 依赖管理:公共依赖提升到根目录,子包间使用
workspace:*协议 - 任务配置:在
turbo.json中准确配置outputs,确保缓存生效 - 版本管理:使用 Changeset 管理版本,仅发布需要发布的包
- 目录结构:按功能拆分(packages、docs、examples),保持清晰
- 避免过度拆分:子包数量控制在 5 个以内,过多会增加配置复杂度
- 开发体验:使用
pnpm run dev同时启动所有子包的开发模式
常见问题
工作区相关问题
Q: 子包间依赖如何引用?
A: 使用工作区协议 workspace:*:
1{ 2 "dependencies": { 3 "@your-org/core": "workspace:*" 4 } 5} 6
Q: 如何安装依赖到特定子包?
A:
1# 安装到根目录 2pnpm add -D typescript -w 3 4# 安装到特定子包 5pnpm add -D vite --filter @your-org/example-basic 6 7# 安装到所有子包 8pnpm add -D eslint --filter "./packages/*" 9
Q: 如何查看所有子包?
A:
1pnpm list -r --depth=0 2
Turbo 相关问题
Q: Turbo 缓存不生效怎么办?
A:
- 检查
turbo.json中的outputs配置是否正确 - 检查构建输出目录是否在
outputs中声明 - 清理缓存:
pnpm run clean && rm -rf .turbo
Q: 如何只构建变更的子包?
A: Turbo 默认就是增量构建,只需执行 pnpm run build,Turbo 会自动判断哪些子包需要重新构建。
Q: 如何跳过缓存强制构建?
A:
1pnpm run build --force 2
Q: 如何查看构建依赖关系?
A:
1# 查看任务依赖图 2npx turbo run build --graph 3
版本管理相关问题
Q: Changeset 如何只发布特定包?
A: 在 .changeset/config.json 中配置 ignore 字段,或在执行 npx changeset 时只选择需要发布的包。
Q: 如何自动化发布流程?
A: 使用 GitHub Actions + Changeset,参考 Changeset 文档。
Q: release-it 能否用于 monorepo?
A: 可以,但主要用于单包发布场景。如果项目只有一个包需要发布,release-it 更简单;如果需要多包版本同步,建议使用 Changeset。
Q: release-it 如何发布 monorepo 中的特定包?
A:
1# 方式一:在子包目录下执行 2cd packages/core 3pnpm run release 4 5# 方式二:使用 pnpm filter 6pnpm --filter @your-org/core run release 7
性能优化相关问题
Q: 如何提升构建速度?
A:
- 配置 Turbo 远程缓存(团队共享)
- 优化
turbo.json的outputs配置 - 使用
dependsOn合理配置任务依赖 - 避免不必要的任务依赖
Q: 如何减少 node_modules 体积?
A:
- 使用 pnpm(默认使用符号链接,节省磁盘空间)
- 公共依赖提升到根目录
- 使用
.npmrc配置shamefully-hoist=false
参考资源
文档版本:v2.0
最后更新:2024 年
《Monorepo 架构以及工具选型、搭建》 是转载文章,点击查看原文。
