Nexjs:turborepo
2026年6月28日monorepo
my-repo/
├─ apps/
│ ├─ web/ ← Next.js アプリ
│ └─ admin/ ← 管理画面アプリ
├─ packages/
│ └─ ui/ ← 共通コンポーネント
└─ package.json1つのフォルダで複数アプリを管理できるという理由で異なる(サブ)ドメインのアプリを詰め込まない方が良い。
tsconfigやpackage.jsonの知識が浅いとturborepoを活用しきれないと感じた。monorepoでは
npmではなくpnpmというパッケージ管理を使う。Vercelでのデプロイ:
apps/webやapps/adminのようにアプリ別にデプロイできる以下の呼び方で統一
App:appsフォルダの中の各アプリ
内部パッケージ:packagesフォルダ内のパッケージ
パッケージ:App・内部パッケージに関わらず
package.jsonがある場合はパッケージ
pnpm
pnpm add ライブラリでインストールしたライブラリはインストールコマンドを実行したパッケージ内のpackage.jsonに依存として記載されるが、ライブラリの実体はUbuntuだと~/.local/share/pnpm/storeにある。各パッケージでそのライブラリを使いたい場合、各パッケージ内の
node_modulesにシンボリックリンクが存在しなければ importできないので、パッケージ側でもpnpm add ライブラリコマンドが必要

pnpm自体のインストール:
npm install -g pnpm
pnpmを使ったライブラリのインストール:
パッケージ内で
pnpm addライブラリ
アプリの起動:
ルートから
pnpm devをするとすべてのアプリが3000ポートから順に開かれるcdでアプリに移動してpnpm devをすると該当アプリのみが起動
package.json: script
"dev:web": "turbo dev --filter=./apps/web",
"dev:admin": "turbo dev --filter=./apps/admin" cdコマンドで各アプリに移動して起動したくない場合
turbo.json:ターミナル
{
"$schema": "https://turbo.build/schema.json",
"ui": "stream",ターミナルのUIは
streamが見やすい
依存関係のupdate:
# ^4.17.15なら4の範囲内
pnpm -r update
# major(一番左の数字)も更新
pnpm -r update -L-r:recursive(再帰的)-L:latest
turborepo
https://turborepo.com/docs/guides/
pnpm dlx shadcn@canary init最初から shadcn と tailwind の設定がされている
packageの作成
https://turborepo.dev/docs/crafting-your-repository/creating-an-internal-packageを参考
重要:
// apps/web/package.json
"dependencies": {
"@repo/ui": "workspace:*",
"@repo/functions": "workspace:*",作成したpackagesからapps側で関数をimportしたい場合、
pnpm iを一度実行して、apps側のnode_modulesにシンボリックリンクを作成する必要がある。
❯ pnpm i
Scope: all 8 workspace projects
../.. | Progress: resolved 308, reused 277, downloaded 0, added 0, d
one
dependencies:
+ @repo/functions 1.0.0 <- ../../packages/functions環境変数
環境変数をapps内の .env に追加してprocess.env. で使おうとすると以下のような警告が出る
GLOBAL_ENV_TEST is not listed as a dependency in root turbo.jsoneslintturbo/no-undeclared-env-vars
string | undefined
turbo.jsonの"env"配列に環境変数を追加すると消える
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
"env": ["SECRET_FROM_DOCS_APP", "GLOBAL_ENV_TEST"]
},turbo.jsonにはNEXT_PUBLICがつく環境変数は追加しなく良い。各appsで環境変数名が同じで値が違うようなケースは問題ない( 例:
DATABASE_URL)
===
*理解していない
turbo.jsonに書かなくてもエラーが出ない環境変数もある。
ビルド時評価が関係?
t3-envのような環境変数の管理を取り入れるとすべてエラーが出る。
キャッシュが関係している?
===
Vercelのデプロイ設定
最初からturborepoで作り始めた場合は何もしなくていい。
途中からプロジェクトをturborepoにした場合、Vercelのアプリダッシュボード/settings/build-and-deploymentからルートディレクトリを のようにして、以下2つの項目にチェックを入れる。
Include files outside the root directory in the Build Step.
Skip deployments when there are no changes to the root directory or its dependencies.上の方は設定したルート(
apps/web)外のファイルもビルドコンテキストに含める設定。turborepoは設定したルート以外のpackageからもファイルを参照する為、必要下の方はルートディレクトリに設定したアプリに変更がない場合、他のアプリに変更があっても再デプロイしない設定
Vercelのデプロイ時間制限に引っかかるのを避ける為
エラー
ローカルでのビルドエラー:Prisma
ローカルでPrisma関連のビルドエラーが出た時の対策:
"compilerOptions": {
"declaration": false,
"declarationMap": false,アプリ内の
tsconfig.jsonに上記を書く。
falseにしても大丈夫化なのか
declarationは型定義ファイル
.d.tsを生成するオプションパッケージとして配布したい場合は影響が出るが、apps側には関係無い。
Vercelデプロイ時のエラー:pnpm
エラー内容( Vercel log ):
ERR_PNPM_OUTDATED_LOCKFILE
Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date原因:同期のズレ
apps側で誤ってnpm iでライブラリを追加するとpnpm.lock.ymlは更新されないので同期がズレる。あるいは手動で
apps側のpackage.jsonのバージョン更新をした後にpnpm i を忘れるなど。
対策:
ルートにある
pnpm-lock.yaml,node_modules,.turboを削除したあとに、pnpm iをする。