途中からTurborepoを導入する

現在Next.jsのApp下にclientとadminのページが存在しているので分けて開発したい
モノレポの知識もないので合わせて勉強する。

モノレポはプロジェクトを単一のリポジトリで合わせて開発する手法らしい
現在もバックとフロントを同一のリポジトリで開発しているためモノレポといえる?
今回はフロント内のNext.jsをさらに分割する。
フロンエンドではプロジェクト間で同一のライブラリや共通して使用できるコンポーネントなどを管理したい。そういった際に使用できるのがTurborepo?Turborepo以外のツールは聞いたことがない()
turborepoは依存関係の自動解決・ビルドキャッシュと並列化を用いてモノレポの問題点である複雑性とビルド時間の増加に対応している

現在のプロジェクトにTurborepoを導入する。
現在のリポジトリではnpmを使用しているがturborepoのインストールセクションでpnpmがデフォルトだったのでpnpmにも移行する(他のライブラリやフレームワークのインストールセクションでもpnpmがデフォルトで選択されていたのでそういう流れ?)

現在の存在するフロント側のディレクトリ名をリネームし同一の名前でturborepoのプロジェクトを作成し以前のコードを移植する計画.
pnpm dlx create-turbo@latest
上記を実行しプロジェクトを作成すると下記のようなものが自動生成される。
apps:プロジェクト
packages:共通するUIや設定
root:全体で使用するコンフィグなど
を配置する感じですね。
.
├── .turbo
│ ├── cache
│ │ ├── 0bbe7ff07823011d-meta.json
│ │ ├── 0bbe7ff07823011d.tar.zst
│ │ ├── 5606935383f1019b-meta.json
│ │ └── 5606935383f1019b.tar.zst
│ ├── cookies
│ │ ├── 1.cookie
│ │ ├── 2.cookie
│ │ ├── 3.cookie
│ │ ├── 4.cookie
│ │ └── 5.cookie
│ ├── daemon
│ │ └── 3edd7b37ebe95808-turbo.log.2025-08-12
│ └── preferences
│ └── tui.json
├── .vscode
│ └── settings.json
├── apps
│ ├── docs
│ │ ├── .turbo
│ │ │ └── turbo-build.log
│ │ ├── app
│ │ │ ├── fonts
│ │ │ │ ├── GeistMonoVF.woff
│ │ │ │ └── GeistVF.woff
│ │ │ ├── favicon.ico
│ │ │ ├── globals.css
│ │ │ ├── layout.tsx
│ │ │ ├── page.module.css
│ │ │ └── page.tsx
│ │ ├── public
│ │ │ ├── file-text.svg
│ │ │ ├── globe.svg
│ │ │ ├── next.svg
│ │ │ ├── turborepo-dark.svg
│ │ │ ├── turborepo-light.svg
│ │ │ ├── vercel.svg
│ │ │ └── window.svg
│ │ ├── .gitignore
│ │ ├── eslint.config.js
│ │ ├── next-env.d.ts
│ │ ├── next.config.js
│ │ ├── package.json
│ │ ├── README.md
│ │ └── tsconfig.json
│ └── web
│ ├── .turbo
│ │ └── turbo-build.log
│ ├── app
│ │ ├── fonts
│ │ │ ├── GeistMonoVF.woff
│ │ │ └── GeistVF.woff
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── layout.tsx
│ │ ├── page.module.css
│ │ └── page.tsx
│ ├── public
│ │ ├── file-text.svg
│ │ ├── globe.svg
│ │ ├── next.svg
│ │ ├── turborepo-dark.svg
│ │ ├── turborepo-light.svg
│ │ ├── vercel.svg
│ │ └── window.svg
│ ├── .gitignore
│ ├── eslint.config.js
│ ├── next-env.d.ts
│ ├── next.config.js
│ ├── package.json
│ ├── README.md
│ └── tsconfig.json
├── packages
│ ├── eslint-config
│ │ ├── base.js
│ │ ├── next.js
│ │ ├── package.json
│ │ ├── react-internal.js
│ │ └── README.md
│ ├── typescript-config
│ │ ├── base.json
│ │ ├── nextjs.json
│ │ ├── package.json
│ │ └── react-library.json
│ └── ui
│ ├── src
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ └── code.tsx
│ ├── eslint.config.mjs
│ ├── package.json
│ └── tsconfig.json
├── .gitignore
├── .npmrc
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── README.md
└── turbo.json
23 directories, 78 files

turborepo用の設定を記述する。(長いのでtrと略す)
trではWorkspace単位で管理を行う。今回生成されたapps/web,apps/docs,packages/ui ...などがワークスペースらしい。
各Workspaceのpackage.jsonのnameがワークスペース名となる。
合わせてnode packageを追加するときと同じ感じに他のワークスペースへの依存関係を記述する。trはこの記述を読み取りビルドの依存関係を解決する
この記述方法はpnpmでの記述方法らしいnpm workspaceでの書き方と異なる
{
// ワークスペース名
"name": "web",
}
....
"dependencies": {
// 共通UIへの依存
"@repo/ui": "workspace:*",
"next": "^15.4.2",
"react": "^19.1.0",
"react-dom": "^19.1.0"
},
"devDependencies": {
// コンフィグへの依存
"@repo/eslint-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@types/node": "^22.15.3",
"@types/react": "19.1.0",
"@types/react-dom": "19.1.1",
"eslint": "^9.31.0",
"typescript": "5.8.2"
}

調べてみた感じpnpm dlx shadcn@canary init
でshadcn用のプロジェクトを作成した方がパスなどの設定をショートカットできそう。
前回作成したプロジェクトを消して前述のコマンドで再作成する。
再作成したプロジェクトではapps/docsは生成されない.
packages/uiにtailwindcss・shadcnコンポーネント・global.cssが置かれWorkspaceからエクスポートされている。

現在のプロジェクトを移行するために新規Next.jsプロジェクトをappsに追加する
appsにnext.jsをpnpmで追加します。※全てデフォルト設定
pnpm create next-app apps/admin -- --typescript
次にtr用の設定を追加します。
こちらはpnpm dlx shadcn@canary init
で生成されたweb ワークスペースを参考にします
adminワークスペースが起動するポートをwebワークスペースと変更し起動するか確認します。( "dev": "next dev --turbopack --port 5000")

自作していたサイドバーなどを新規に作成したAdmin Workspaceに移植してインポートを書き換えた。
CSSが当たっていなかったため。
以下を設定
// postcss.config.mjs
export { default } from "@workspace/ui/postcss.config";
// page.tsx
import "@workspace/ui/globals.css";
表示も問題なさそうなので同一の手順でclient側も移植する