turborepo
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseturborepo
turborepo
方針
原则
Turborepo と pnpm ワークスペースの組み合わせに従う。パッケージマネージャーは pnpm に統一し、ロックファイルは pnpm-lock.yaml だけをコミットする。
Turborepo は更新が速く、turbo.json のキー名も変わってきている。設定の形に迷ったら記憶に頼らず下を引く。
- ドキュメント https://turborepo.dev/docs
- turbo.json のリファレンス https://turborepo.dev/docs/reference/configuration
- タスクの構成 https://turborepo.dev/docs/crafting-your-repository/configuring-tasks
- キャッシュ https://turborepo.dev/docs/crafting-your-repository/caching
- 複数言語の扱い https://turborepo.dev/docs/guides/multi-language
- 更新情報 https://turborepo.dev/blog
- リリースと破壊的変更 https://github.com/vercel/turborepo/releases
turbo.json のタスク定義キーは v2 以降 tasks。pipeline は旧名。古い記事を写さない。
Turborepo をグローバルにインストールしない。 を使うか、ルートの devDependency として入れる。
pnpm exec turbo遵循 Turborepo 与 pnpm 工作空间的组合方式。统一使用 pnpm 作为包管理器,锁文件只提交 pnpm-lock.yaml。
Turborepo 更新频繁,turbo.json 的键名也一直在变化。如果不确定配置形式,不要依赖记忆,应查阅以下资料。
- 文档 https://turborepo.dev/docs
- turbo.json 参考 https://turborepo.dev/docs/reference/configuration
- 任务配置 https://turborepo.dev/docs/crafting-your-repository/configuring-tasks
- 缓存 https://turborepo.dev/docs/crafting-your-repository/caching
- 多语言支持 https://turborepo.dev/docs/guides/multi-language
- 更新动态 https://turborepo.dev/blog
- 版本发布与破坏性变更 https://github.com/vercel/turborepo/releases
turbo.json 的任务定义键从 v2 开始为 tasks。pipeline 是旧名称。不要照搬旧文章。
不要在全局安装 Turborepo。使用 ,或者将其添加为根目录的 devDependency。
pnpm exec turbo構成
结构
text
my-monorepo/
pnpm-workspace.yaml
turbo.json
package.json
apps/ デプロイ可能なアプリケーション
packages/ 共有ライブラリと設定- ワークスペース構成は pnpm-workspace.yaml で定義する。
- apps と packages の分離を維持する。デプロイ可能なアプリを packages に置かない。共有ライブラリを apps に置かない。
- ネストしたパッケージを作らない。
text
my-monorepo/
pnpm-workspace.yaml
turbo.json
package.json
apps/ 可部署的应用程序
packages/ 共享库和配置- 工作空间配置通过 pnpm-workspace.yaml 定义。
- 保持 apps 和 packages 分离。不要把可部署的应用放入 packages,也不要把共享库放入 apps。
- 不要创建嵌套包。
パッケージ
包
- 名前は プレフィックスを持つスコープ付きにする。
@<org>/ - 内部パッケージにはすべて を設定する。
"private": true - 各 package.json に exports を定義する。main より exports を優先する。
- 共有 TypeScript 設定を packages/tsconfig/ に置き、各パッケージがそれを継承する。
- 内部依存は プロトコルで参照する。
workspace:*
- 名称使用带 前缀的 scoped 格式。
@<org>/ - 所有内部包都设置 。
"private": true - 在每个 package.json 中定义 exports。优先使用 exports,而不是 main。
- 将共享 TypeScript 配置放在 packages/tsconfig/ 中,并由各个包继承。
- 内部依赖使用 协议引用。
workspace:*
責務パッケージ
职责包
次を packages 配下に必ず置く。
- log ログ集約
- error エラー集約
- prompt AI プロンプト集約
- env 環境変数集約
- db データベース集約
利用側は などを で依存に追加する。該当する責務を呼び出し側で再実装しない。
@<org>/logworkspace:*以下职责包必须放在 packages 目录下。
- log:日志汇总
- error:错误汇总
- prompt:AI 提示词汇总
- env:环境变量汇总
- db:数据库汇总
使用方通过 添加 等依赖。不要在调用方重新实现相应的职责。
workspace:*@<org>/logpackage.json の生成と更新
package.json 的生成与更新
package.json をゼロから手書きしない。ルート、apps/、packages/ のいずれでも同じ。
sh
pnpm init # package.json を生成する
pnpm create <template> # フレームワークの scaffolder を使う依存関係の追加、更新、削除はコマンドで行う。
sh
pnpm add -D -w turbo typescript # ルートの devDependency
pnpm add --filter @<org>/dashboard zod # 特定パッケージの外部依存
pnpm add --filter @<org>/dashboard --workspace @<org>/log # 内部依存を workspace:* で解決
pnpm update --filter @<org>/dashboard
pnpm remove --filter @<org>/dashboard zod- ルート以外を対象にするときは でパッケージを指定する。
--filter - ワークスペース内部依存には を併用する。
--workspace - dependencies、devDependencies、peerDependencies を直接編集しない。
- コマンドで設定できないフィールド(name のスコープ化、private、exports、scripts)だけ、生成済みの package.json に最小限の編集を加える。
不要从零开始手动编写 package.json。无论操作根目录、apps/* 还是 packages/*,都遵循相同方式。
sh
pnpm init # package.json を生成する
pnpm create <template> # フレームワークの scaffolder を使う通过命令添加、更新和删除依赖。
sh
pnpm add -D -w turbo typescript # ルートの devDependency
pnpm add --filter @<org>/dashboard zod # 特定パッケージの外部依存
pnpm add --filter @<org>/dashboard --workspace @<org>/log # 内部依存を workspace:* で解決
pnpm update --filter @<org>/dashboard
pnpm remove --filter @<org>/dashboard zod- 操作根目录以外的目标时,使用 指定包。
--filter - 添加工作空间内部依赖时,同时使用 。
--workspace - 不要直接编辑 dependencies、devDependencies、peerDependencies。
- 仅对无法通过命令配置的字段,如 name 的 scoped 格式、private、exports 和 scripts,在生成的 package.json 中进行最小幅度的编辑。
手順例
操作示例
sh
undefinedsh
undefinedルートワークスペース
ルートワークスペース
mkdir my-monorepo && cd my-monorepo
pnpm init
mkdir my-monorepo && cd my-monorepo
pnpm init
pnpm-workspace.yaml に apps/* と packages/* を定義する
pnpm-workspace.yaml に apps/* と packages/* を定義する
pnpm add -D -w turbo typescript
pnpm add -D -w turbo typescript
責務パッケージ
責務パッケージ
mkdir -p packages/log
(cd packages/log && pnpm init)
mkdir -p packages/log
(cd packages/log && pnpm init)
name を @<org>/log にし、private と exports を設定する
name を @<org>/log にし、private と exports を設定する
アプリ
アプリ
pnpm create next-app@latest apps/dashboard
pnpm add --filter @<org>/dashboard --workspace @<org>/log
undefinedpnpm create next-app@latest apps/dashboard
pnpm add --filter @<org>/dashboard --workspace @<org>/log
undefinedturbo.json
turbo.json
依存関係を考慮したタスクパイプラインを定義する。
json
{
"$schema": "https://turborepo.dev/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
},
"lint": {},
"test": { "dependsOn": ["^build"] },
"dev": { "cache": false, "persistent": true }
}
}- は依存パッケージのタスクを先に走らせる指定。
^build - outputs を正確に書く。書き漏らすとキャッシュから復元されない。
- dev のような常駐タスクは と
cache: falseにする。persistent: true - 環境変数がビルド結果に影響するなら env に列挙する。列挙しないと環境が違ってもキャッシュが当たる。
定义考虑依赖关系的任务流水线。
json
{
"$schema": "https://turborepo.dev/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
},
"lint": {},
"test": { "dependsOn": ["^build"] },
"dev": { "cache": false, "persistent": true }
}
}- 表示先运行依赖包中的任务。
^build - 准确填写 outputs。遗漏文件会导致这些文件无法从缓存中恢复。
- 对于 dev 等常驻任务,设置 和
cache: false。persistent: true - 如果环境变量会影响构建结果,应在 env 中列出。否则即使环境不同,也可能会命中缓存。
コンパイル方針
编译策略
デフォルトは JIT(Just-in-Time)コンパイルパターンを採る。tsc で dist に出すコンパイル済みパターンへの切り替えは、明示的に要求されたときだけ行う。
默认采用 JIT(Just-in-Time)编译模式。只有在明确要求时,才切换为使用 tsc 编译到 dist 的预编译模式。
非 JavaScript プロジェクト
非 JavaScript 项目
Turborepo は JavaScript 専用ではない。Cargo、Go、Python などのプロジェクトも同じタスクグラフに載せられる。
Rust(Cargo)と Python は、独立してキャッシュしたい単位ごとに package.json を置き、その scripts から各言語のツールチェーンを呼ぶ。Turborepo はネイティブの依存グラフを解析せず、パッケージマネージャー上の関係を使う。
json
{
"name": "@<org>/engine",
"private": true,
"scripts": {
"build": "cargo build --release",
"test": "cargo test",
"lint": "cargo clippy -- -D warnings"
}
}turbo.json 側で inputs と outputs を書き、キャッシュを効かせる。
json
{
"tasks": {
"build": {
"inputs": ["src/**", "Cargo.toml", "Cargo.lock"],
"outputs": ["target/release/**"]
}
}
}- inputs を絞らないと、無関係なファイルの変更でキャッシュが外れる。
- outputs に target 全体を指定すると成果物が巨大になる。必要なパスだけ指定する。
- Cargo 自身のインクリメンタルキャッシュと二重になる。どちらで効かせるかを決めてから設定する。
Go は experimental なネイティブ対応がある。turbo.json で futureFlags を有効にし、go.work にモジュールを列挙する。この場合 Go パッケージ側に package.json は不要で、モジュールパスがパッケージの識別子になる。
json
{
"futureFlags": { "experimentalGoWorkspaces": true }
}experimental なので挙動が変わり得る。採用前に上のドキュメントで現状を確認する。
Turborepo 并非只支持 JavaScript。Cargo、Go、Python 等项目也可以加入同一个任务图。
对于 Rust(Cargo)和 Python,按照需要独立缓存的单位放置 package.json,并通过 scripts 调用相应语言的工具链。Turborepo 不会分析原生依赖图,而是使用包管理器所维护的依赖关系。
json
{
"name": "@<org>/engine",
"private": true,
"scripts": {
"build": "cargo build --release",
"test": "cargo test",
"lint": "cargo clippy -- -D warnings"
}
}在 turbo.json 中配置 inputs 和 outputs,以启用缓存。
json
{
"tasks": {
"build": {
"inputs": ["src/**", "Cargo.toml", "Cargo.lock"],
"outputs": ["target/release/**"]
}
}
}- 如果不限制 inputs,无关文件的修改也会导致缓存失效。
- 如果在 outputs 中指定整个 target,产物体积会非常大。只指定必要的路径。
- 这可能与 Cargo 自身的增量缓存重复。配置前应决定使用哪一种缓存机制。
Go 目前具有 experimental 的原生支持。在 turbo.json 中启用 futureFlags,并在 go.work 中列出模块。在这种情况下,Go 包一侧不需要 package.json,模块路径将作为包的标识符。
json
{
"futureFlags": { "experimentalGoWorkspaces": true }
}由于该功能仍为 experimental,其行为可能发生变化。采用前应查阅上述文档以确认当前状态。
確定前に確認する
完成前确认
- pnpm 以外のロックファイル(package-lock.json、yarn.lock)が混ざっていないか。
- デプロイ可能なアプリが packages に、共有ライブラリが apps に入っていないか。
- 内部依存が になっているか。
workspace:* - 各パッケージが private と exports を持ち、共有 tsconfig を継承しているか。
- 責務パッケージを呼び出し側で再実装していないか。
- turbo.json のキーが tasks になっているか。pipeline のまま残っていないか。
- outputs と inputs と env が正確か。キャッシュが誤って当たる、または常に外れる状態になっていないか。
- 依存の追加を手書きの package.json 編集で済ませていないか。
- turbo をグローバルインストールしていないか。
- 是否混入了 pnpm 以外的锁文件,如 package-lock.json、yarn.lock。
- 可部署的应用是否被放入 packages,共享库是否被放入 apps。
- 内部依赖是否使用了 。
workspace:* - 每个包是否都设置了 private 和 exports,并继承了共享 tsconfig。
- 是否在调用方重新实现了职责包的功能。
- turbo.json 的键是否使用 tasks,而不是仍然保留 pipeline。
- outputs、inputs 和 env 是否准确,是否避免了缓存错误命中或始终失效。
- 是否通过手动编辑 package.json 来添加依赖。
- 是否在全局安装了 turbo。