メインコンテンツまでスキップ

Cursor でのモノレポ管理:Turborepo、Nx、pnpm Workspaces

Monorepo Management in Cursor

モノレポを使用すると、複数のパッケージやアプリケーションを単一のリポジトリに保持し、コード、設定、ツールを共有できます。AI駆動の IDE エディタである Cursor は、クロスパッケージの関係を理解し、パイプライン設定を生成し、共有 API を安全にリファクタリングすることで、モノレポ管理を劇的に簡単にします。このガイドは、Turborepo、Nx、pnpm workspaces と、AI支援の依存関係管理およびクロスパッケージリファクタリングの実践的なテクニックをカバーします。

前提条件​

始める前に、以下のものを用意してください:

  • IDE エディタとしての Cursor(最新バージョンを推奨)
  • Node.js 18 以上
  • グローバルにインストールされた pnpm(npm install -g pnpm)
  • パッケージマネージャーとワークスペースに関する基本的な知識
ヒント

Cursor の組み込みターミナルとマルチルートワークスペースのサポートにより、モノレポに最適です。Cursor でリポジトリルートを開くと、AI がすべてのパッケージを一度に確認できます。これにより、クロスパッケージのリファクタリングと依存関係分析のための完全なコンテキストがエディタに与えられます。

モノレポツールの選択​

3つのツールが JavaScript と TypeScript のモノレポ領域を支配しています。それぞれ異なる強みがあります:

ツール最適な用途主要な強み
pnpm workspaces小〜中規模のモノレポ高速でディスク効率の良いインストール
Turborepoアプリ中心のモノレポシンプルなタスクキャッシュと並列実行
Nx大規模でプラグインが多いモノレポ強力なコード生成と依存関係グラフ

Cursor の AI にあなたの状況に合ったツールの推奨を依頼します:

I have a monorepo with 2 Next.js apps, a shared React component library,
and 3 utility packages. Should I use Turborepo or Nx? Compare them.

Cursor はトレードオフを説明し、選択したツールのスターター設定を生成します。

Cursor での pnpm Workspaces のセットアップ​

pnpm workspaces は、その速度とハードリンクによるディスク効率のため、ほとんどのモダンなモノレポの基盤です。Cursor はワークスペースの定義と最初のパッケージのブートストラップを支援します。

ワークスペースルートの作成​

Cursor で新しいフォルダを開き、AI に pnpm ワークスペースのスキャフォールディングを依頼します:

Create a pnpm workspace monorepo with:
- A root package.json with pnpm workspace config
- A pnpm-workspace.yaml listing apps/* and packages/*
- A shared TypeScript config package
- An .npmrc with shared-cache settings

Cursor はルートファイルを生成します:

# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
// package.json
{
"name": "cursor-monorepo",
"private": true,
"scripts": {
"dev": "pnpm -r --parallel run dev",
"build": "pnpm -r run build",
"lint": "pnpm -r run lint",
"test": "pnpm -r run test"
},
"devDependencies": {
"typescript": "^5.4.0"
}
}
# .npmrc
shared-cache-max-age=86400
auto-install-peers=true
strict-peer-dependencies=false

最初のパッケージの作成​

Cursor に共有 UI パッケージとそれを使用する Web アプリの生成を依頼します:

Create a packages/ui React component library and an apps/web Next.js app.
The web app should depend on the ui package using workspace:* protocol.

Cursor はパッケージ構造を生成します:

monorepo/
apps/
web/
package.json
src/
app/page.tsx
packages/
ui/
package.json
src/
index.ts
Button.tsx
pnpm-workspace.yaml
package.json

packages/ui/package.json:

{
"name": "@cursor-monorepo/ui",
"version": "0.1.0",
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"lint": "eslint .",
"build": "tsc"
},
"peerDependencies": {
"react": "^18.0.0"
}
}

apps/web/package.json はワークスペースプロトコルを使用して共有パッケージを参照します:

{
"name": "@cursor-monorepo/web",
"version": "0.1.0",
"dependencies": {
"@cursor-monorepo/ui": "workspace:*",
"next": "^14.0.0",
"react": "^18.0.0"
}
}

Cursor のターミナルからルートでインストールを実行します:

pnpm install

pnpm は依存関係をハードリンクするため、インストールが高速でディスク効率が高いです。

警告

内部パッケージを参照する際は、常に workspace:* プロトコル(または workspace:^)を使用してください。1.0.0 のようにバージョン番号を固定すると、pnpm はローカルパッケージを解決する代わりにレジストリからパッケージを取得しようとし、インストール時に混乱を招く「パッケージが見つかりません」エラーが発生します。

Cursor での Turborepo 統合​

Turborepo は pnpm workspaces の上にキャッシュと並列タスク実行を追加します。Cursor はパイプライン設定を生成し、チューニングを支援します。

既存のワークスペースへの Turborepo の追加​

Cursor にモノレポへ Turborepo を追加するよう依頼します:

Add Turborepo to my pnpm workspace. Create a turbo.json with build,
dev, lint, and test pipelines. Configure build dependencies and caching.

Cursor は依存関係をインストールし、turbo.json を生成します:

pnpm add -Dw turbo
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
"inputs": [
"src/**",
"package.json",
"tsconfig.json"
]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {
"dependsOn": ["^build"],
"outputs": []
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["src/**", "test/**", "package.json"]
}
}
}

dependsOn: ["^build"] ディレクティブは、Turborepo にパッケージ自体をビルドする前にパッケージの依存関係をビルドするよう指示します。これは、アプリが共有ライブラリに依存するモノレポにおいて重要です。

Turbo でのタスク実行​

Cursor のターミナルからモノレポ全体でタスクを実行します:

# Build all packages in topological order
pnpm turbo run build

# Run dev servers in parallel
pnpm turbo run dev --parallel

# Filter to a single package and its dependents
pnpm turbo run build --filter=@cursor-monorepo/web...

... サフィックスは「このパッケージとそれに依存するすべて」を意味し、共有ライブラリを変更する際の影響分析に役立ちます。

ヒント

--filter フラグと ^ プレフィックスを使用して、パッケージとその依存関係のタスクのみを実行します。例えば、pnpm turbo run build --filter=^@cursor-monorepo/web は Web アプリが必要とするパッケージのみをビルドし、無関係な作業をスキップします。これは高速なローカルフィードバックループに非常に役立ちます。

リモートキャッシュの設定​

リモートキャッシュにより、チームがビルド結果を共有できます。Cursor に Vercel リモートキャッシュのセットアップを依頼します:

Configure Turborepo remote caching for my monorepo. Generate the
.nenv example and explain how to link the cache.

Cursor は手順を説明します:

npx turbo login
npx turbo link

キャッシュキーに適切な変数が含まれるように、turbo.json に環境ヒントを追加します:

{
"globalEnv": ["NODE_ENV", "CI"]
}

Cursor での Nx 統合​

Nx は、コードジェネレーター、依存関係グラフ、多くのフレームワークのプラグインサポートを備えた、より強力なモノレポツールです。Cursor は Nx プロジェクトのブートストラップと拡張を支援します。

Nx ワークスペースの作成​

Cursor に Nx ワークスペースの作成を依頼します:

Create an Nx integrated monorepo with:
- A React app named storefront
- A Node API app named api
- A shared types library
- pnpm as the package manager

Cursor はスキャフォールディングを実行し、結果を説明します:

npx create-nx-workspace@latest cursor-nx --preset=apps --packageManager=pnpm

結果の構造:

cursor-nx/
apps/
storefront/
api/
libs/
types/
nx.json
project.json

Nx プラグインによるコード生成​

Nx プラグインは一貫したスキャフォールディングのためのジェネレーターを提供します。Cursor に React コンポーネントライブラリの生成を依頼します:

Generate a React library named ui with buildable true and
Storybook configuration using the @nx/react plugin.
npx nx g @nx/react:library ui --buildable --storybook --directory=libs/ui

依存関係グラフの可視化​

Nx にはグラフビジュアライザーが付属しています。Cursor のターミナルから実行します:

npx nx graph

ブラウザでインタラクティブなグラフが開き、パッケージ間の依存関係を表示します。Cursor の AI は依頼すればテキストでグラフを説明することもできます:

List all packages that depend on libs/types and would break if I
renamed its default export.

Cursor はワークスペース設定を読み取り、影響分析を返します。これは共有コードのリファクタリング前に不可欠です。

警告

Nx 統合ワークスペースは、インポートのために tsconfig.base.json でパスマッピングを使用します。新しいライブラリを追加する場合、paths マッピングを更新しないと TypeScript がインポートを解決できません。「Cannot find module」エラーが表示された場合、Cursor の AI が欠落しているパスマッピングを検出し、修正を提案できます。

AI 支援の依存関係管理​

モノレポ全体で依存関係の一貫性を維持することは、最も困難なメンテナンスタスクの一つです。Cursor の AI はこれに優れています。

バージョンの不整合の監査​

Cursor に依存関係の不整合の検出を依頼します:

Scan all package.json files in my monorepo and report any
dependencies that have inconsistent versions across packages.
Suggest a single pinned version for each.

Cursor はすべての package.json を読み取り、不整合をリストし、それらを整列させるスクリプトを生成できます:

# Align react to 18.2.0 everywhere

未使用の依存関係の検出​

Cursor は package.json で宣言されているがインポートされていないパッケージを検出できます。尋ねます:

Find unused dependencies in the apps/web package by checking
imports across all source files.

Cursor は未使用のエントリを報告し、削除コマンドを提案します:

pnpm --filter @cursor-monorepo/web remove unused-package-name

共有開発依存関係の管理​

バージョンのドリフトを避けるため、共有開発ツール(ESLint、Prettier、TypeScript)をワークスペースルートに引き上げます。Cursor は共有設定パッケージを生成します:

Create a packages/config package that exports shared ESLint,
TypeScript, and Prettier configs so other packages can extend them.
// packages/config/package.json
{
"name": "@cursor-monorepo/config",
"version": "0.1.0",
"files": ["eslint", "tsconfig", "prettier"],
"devDependencies": {
"eslint": "^8.57.0",
"prettier": "^3.2.0"
}
}
// packages/config/eslint/base.js
module.exports = {
extends: ['next', 'prettier'],
rules: {
'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
'no-console': ['warn', { allow: ['warn', 'error'] }],
},
};

他のパッケージは共有設定を継承します:

{
"eslintConfig": { "extends": "@cursor-monorepo/config/eslint" }
}
ヒント

pnpm の catalog 機能(または Renovate)を使用して、バージョン番号を一元化します。Cursor に「すべての共有依存関係バージョンに pnpm catalog を設定して」と依頼すると、pnpm-workspace.yaml の catalog ブロックを作成し、単一のバージョン更新がすべての場所に自動的に伝播するようにします。

Cursor でのクロスパッケージリファクタリング​

共有 API のリファクタリングはすべてのコンシューマーに影響します。Cursor のコードベースインデックスにより、AI はモノレポ全体の使用状況を追跡でき、大規模なリファクタリングを安全にします。

共有エクスポートのリネーム​

packages/ui の Button コンポーネントを ActionButton にリネームしたいとします。Cursor の Agent に依頼します:

Rename the Button component to ActionButton across the entire
monorepo. Update the export, the type, all imports, and the
Storybook stories. Run the build to verify nothing is broken.

Cursor はマルチファイル編集を一括で実行します:

// packages/ui/src/ActionButton.tsx
import React from 'react';

export interface ActionButtonProps {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
}

export const ActionButton = ({ label, onClick, variant = 'primary' }: ActionButtonProps) => (
<button className={`btn btn-${variant}`} onClick={onClick}>
{label}
</button>
);
// packages/ui/src/index.ts
export { ActionButton } from './ActionButton';
export type { ActionButtonProps } from './ActionButton';
// apps/web/src/app/page.tsx
import { ActionButton } from '@cursor-monorepo/ui';

export default function Home() {
return <ActionButton label="Get Started" onClick={() => alert('hi')} />;
}

共有ユーティリティの抽出​

パッケージ間で重複するロジックを見つけた場合、Cursor に抽出を依頼します:

Extract the date formatting logic duplicated in apps/web and apps/api
into a new shared package called @cursor-monorepo/format. Update all
call sites to import from the new package.

Cursor はパッケージを作成し、コードを移動し、インポートを更新し、影響を受けるビルドを実行して成功を確認します。

警告

クロスパッケージリファクタリングの後は、常に完全なテストスイートとワークスペース全体の型チェックを実行してください。単一の見落とされたインポートは、単独ではコンパイルできますが、パッケージが組み合わさると失敗する可能性があります。ルートから pnpm -r run build && pnpm -r run test を実行して、これらの問題を早期に発見してください。

ワークスペース設定とツール​

パッケージ間で一貫したツールはモノレポを健全に保ちます。Cursor は TypeScript、ESLint、CI の共有設定を生成できます。

共有 TypeScript 設定​

Create a shared tsconfig base at packages/config/tsconfig/base.json
with strict mode, path aliases, and modern lib settings.
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"strict": true,
"noUncheckedIndexedAccess": true,
"moduleResolution": "bundler",
"module": "ESNext",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
}
}

各パッケージはこれを継承します:

{
"extends": "@cursor-monorepo/config/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}

GitHub Actions による CI パイプライン​

Cursor に Turborepo キャッシュを活用する CI パイプラインの生成を依頼します:

Create a GitHub Actions workflow that:
- Installs pnpm and Node
- Restores the pnpm store cache
- Runs turbo run lint build test with caching
- Only runs affected tasks on pull requests
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- uses: actions/cache@v4
with:
path: .turbo
key: turbo-${{ runner.os }}-${{ github.sha }}
restore-keys: turbo-${{ runner.os }}-
- run: pnpm turbo run lint build test

ベストプラクティスのまとめ​

Cursor でモノレポを管理する際、以下の原則を心に留めてください:

  • ワークスペースルートを開く ことで、Cursor がクロスパッケージのコンテキストのためにすべてのパッケージを確認できるようにします。
  • ワークスペースプロトコル(workspace:*)を内部パッケージ参照に使用します。
  • 共有開発ツールを 設定パッケージに引き上げてバージョンドリフトを回避します。
  • タスクキャッシュを活用(Turborepo または Nx)して CI を高速に保ちます。
  • 共有 API のリファクタリング前に影響分析を実行します。
  • バージョンを一元化 pnpm catalogs または Renovate で。

堅牢なモノレポツールと Cursor の AI 駆動のコードベース理解を組み合わせることで、共有コードを自信を持ってリファクタリングし、依存関係を整列させ、多くのパッケージにわたって一貫したツールを提供できます。意図を明確に記述し、Cursor にボイラープレートとクロスファイル編集を任せ、コミット前に生成された diff をレビューしてください。