Loading...
Loading...
Compare original and translation side by side
turbo.jsonturbo.jsonflowchart TD
A[Monorepo tool needed] --> B{Team size and complexity?}
B -->|Small team, apps-first| C{Need plugin ecosystem?}
B -->|Large org, many teams| D[Rush or Nx]
C -->|No — just fast builds| E[Turborepo]
C -->|Yes — code gen, generators| F[Nx]
D --> G{Microsoft/enterprise patterns?}
G -->|Yes| H[Rush]
G -->|No| I[Nx]
E --> J{Package manager preference?}
J -->|pnpm — recommended| K[pnpm + Turborepo]
J -->|npm or yarn| L[npm/yarn workspaces + Turborepo]
I --> M[Nx Cloud for remote caching]
H --> N[Rush's own cache]
K --> O[Vercel Remote Cache\nor self-hosted]flowchart TD
A[Monorepo tool needed] --> B{Team size and complexity?}
B -->|Small team, apps-first| C{Need plugin ecosystem?}
B -->|Large org, many teams| D[Rush or Nx]
C -->|No — just fast builds| E[Turborepo]
C -->|Yes — code gen, generators| F[Nx]
D --> G{Microsoft/enterprise patterns?}
G -->|Yes| H[Rush]
G -->|No| I[Nx]
E --> J{Package manager preference?}
J -->|pnpm — recommended| K[pnpm + Turborepo]
J -->|npm or yarn| L[npm/yarn workspaces + Turborepo]
I --> M[Nx Cloud for remote caching]
H --> N[Rush's own cache]
K --> O[Vercel Remote Cache\nor self-hosted]| Tool | Best For | Remote Cache | Learning Curve |
|---|---|---|---|
| Turborepo | Apps-first, fast builds, simple config | Vercel / self-hosted | Low |
| Nx | Library-heavy, code generation, plugin ecosystem | Nx Cloud / self-hosted | Medium |
| Rush | Enterprise, Microsoft stack, strict isolation | Custom | High |
| Lerna | Legacy — migrating from | None (use with Turborepo) | Low |
| 工具 | 最佳适用场景 | 远程缓存支持 | 学习曲线 |
|---|---|---|---|
| Turborepo | 以应用为核心、快速构建、配置简单 | Vercel / 自托管 | 低 |
| Nx | 以库为核心、代码生成、插件生态丰富 | Nx Cloud / 自托管 | 中 |
| Rush | 企业级、微软技术栈、严格隔离 | 自定义 | 高 |
| Lerna | 遗留项目迁移 | 无(需搭配Turborepo使用) | 低 |
flowchart TD
A[New package in monorepo?] --> B{Who consumes it?}
B -->|Internal only, not published| C[Internal package:\nno versioning, workspace: protocol]
B -->|Published to npm| D[Published package:\nChangesets, semver, CHANGELOG]
B -->|Shared config only| E[Config package:\neslint-config-*, tsconfig-*]
C --> F{What type?}
F -->|UI components| G[packages/ui]
F -->|Business logic / utilities| H[packages/utils or packages/core]
F -->|Shared types| I[packages/types]
F -->|API client| J[packages/api-client]
D --> K[packages/publishable-name]
A --> L{Is it an application?}
L -->|Yes| M[apps/ directory:\nnext-app, api, docs-site]flowchart TD
A[New package in monorepo?] --> B{Who consumes it?}
B -->|Internal only, not published| C[Internal package:\nno versioning, workspace: protocol]
B -->|Published to npm| D[Published package:\nChangesets, semver, CHANGELOG]
B -->|Shared config only| E[Config package:\neslint-config-*, tsconfig-*]
C --> F{What type?}
F -->|UI components| G[packages/ui]
F -->|Business logic / utilities| H[packages/utils or packages/core]
F -->|Shared types| I[packages/types]
F -->|API client| J[packages/api-client]
D --> K[packages/publishable-name]
A --> L{Is it an application?}
L -->|Yes| M[apps/ directory:\nnext-app, api, docs-site]graph LR
A[apps/web] --> B[packages/ui]
A --> C[packages/utils]
A --> D[packages/types]
E[apps/api] --> C
E --> D
B --> D
F[packages/ui-icons] --> D
B --> F
style A fill:#4a9d9e,color:#fff
style E fill:#4a9d9e,color:#fff
style B fill:#6b7280,color:#fff
style C fill:#6b7280,color:#fff
style D fill:#9ca3af
style F fill:#9ca3afpackages/typespackages/uitypesapps/webgraph LR
A[apps/web] --> B[packages/ui]
A --> C[packages/utils]
A --> D[packages/types]
E[apps/api] --> C
E --> D
B --> D
F[packages/ui-icons] --> D
B --> F
style A fill:#4a9d9e,color:#fff
style E fill:#4a9d9e,color:#fff
style B fill:#6b7280,color:#fff
style C fill:#6b7280,color:#fff
style D fill:#9ca3af
style F fill:#9ca3afpackages/typespackages/uitypesapps/web{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "package.json", "tsconfig.json"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"test": {
"dependsOn": ["^build"],
"inputs": ["src/**/*.ts", "src/**/*.tsx", "**/*.test.ts", "**/*.test.tsx"],
"outputs": ["coverage/**"]
},
"lint": {
"inputs": ["src/**/*.ts", "src/**/*.tsx", ".eslintrc*"]
},
"typecheck": {
"dependsOn": ["^build"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}^buildinputsoutputscache: falsepersistent: true{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "package.json", "tsconfig.json"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"test": {
"dependsOn": ["^build"],
"inputs": ["src/**/*.ts", "src/**/*.tsx", "**/*.test.ts", "**/*.test.tsx"],
"outputs": ["coverage/**"]
},
"lint": {
"inputs": ["src/**/*.ts", "src/**/*.tsx", ".eslintrc*"]
},
"typecheck": {
"dependsOn": ["^build"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}^buildinputsoutputscache: falsepersistent: trueundefinedundefinedundefinedundefinedundefinedundefined
Self-hosted alternative: `turbo-remote-cache` package or Turborepo's built-in HTTP cache server in Turborepo 2.x.
**Consult** `references/turborepo-patterns.md` for Docker pruning for deployment, scoped filtering, and advanced pipeline patterns.
---
自托管替代方案:使用`turbo-remote-cache`包,或Turborepo 2.x内置的HTTP缓存服务器。
**进阶参考**:`references/turborepo-patterns.md` 包含部署时的Docker清理、范围过滤及高级流水线模式。
---packages:
- 'apps/*'
- 'packages/*'
- 'tools/*'packages:
- 'apps/*'
- 'packages/*'
- 'tools/*'{
"dependencies": {
"@myorg/ui": "workspace:*",
"@myorg/utils": "workspace:^1.0.0"
}
}workspace:*workspace:^{
"dependencies": {
"@myorg/ui": "workspace:*",
"@myorg/utils": "workspace:^1.0.0"
}
}workspace:*workspace:^undefinedundefined
`shamefully-hoist=true` is a trap: it makes all packages available everywhere but breaks encapsulation. If your tools require it, fix the tool dependency instead.
---
`shamefully-hoist=true`是陷阱:它会让所有包在全局可用,但会破坏依赖隔离。如果你的工具要求启用该选项,请修复工具的依赖问题而非启用它。
---undefinedundefinedundefinedundefined{
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@myorg/app-web", "@myorg/app-api"]
}access: "public"ignorereferences/workspace-architecture.md{
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@myorg/app-web", "@myorg/app-api"]
}access: "public"ignorereferences/workspace-architecture.mdundefinedundefined - uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: Build affected packages
run: pnpm turbo build --filter=...[origin/main]
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
- name: Test affected packages
run: pnpm turbo test --filter=...[origin/main]
`--filter=...[origin/main]` means "run for packages whose files changed compared to `main`, plus all packages that depend on them (upstream consumers)."
--- - uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: Build affected packages
run: pnpm turbo build --filter=...[origin/main]
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
- name: Test affected packages
run: pnpm turbo test --filter=...[origin/main]
`--filter=...[origin/main]`表示「对与`main`相比有文件变更的包,以及所有依赖这些包的上游消费者执行任务」。
---turbo buildinputs.DS_Storenode_modulesturbo build --verbosity=2.turboinputsturbo.jsonoutputs.gitignore.turboignoreinputsoutputsturbo buildinputs.DS_Storenode_modulesturbo build --verbosity=2.turboturbo.jsoninputsoutputs.gitignore.turboignoreinputsoutputspackages/authpackages/api-clientpackages/api-clientpackages/authundefinedpackages/authpackages/api-clientpackages/api-clientpackages/authundefined
**Fix**:
**Timeline**: This is not a new problem — circular deps have been a JavaScript packaging issue since npm v1 (2010). The reason it appears in monorepos specifically is that workspace packages make it easy to import across package boundaries without thinking about dependency direction.
---
**修复方案**:
**历史背景**:这并非新问题——自npm v1(2010年)以来,循环依赖一直是JavaScript打包的痛点。它在Monorepo中频繁出现的原因是,工作区包之间的跨包导入过于便捷,容易忽略依赖方向。
---shamefully-hoist=trueshamefully-hoist=true.npmrcshamefully-hoistnode_modulespublic-hoist-pattern.npmrcshamefully-hoist=truereferences/turborepo-patterns.mdreferences/workspace-architecture.mdreferences/turborepo-patterns.mdreferences/workspace-architecture.md