Zum Hauptinhalt springen

Monorepo-Verwaltung in Cursor: Turborepo, Nx und pnpm-Workspaces

Monorepo-Verwaltung in Cursor

Monorepos ermöglichen es Ihnen, mehrere Pakete oder Anwendungen in einem einzigen Repository zu verwalten, Code, Konfiguration und Tooling zu teilen. Cursor, ein KI-gestützter IDE-Editor, macht die Monorepo-Verwaltung deutlich einfacher, indem er paketübergreifende Beziehungen versteht, Pipeline-Konfigurationen generiert und gemeinsam genutzte APIs sicher refactort. Dieser Leitfaden behandelt Turborepo, Nx und pnpm-Workspaces mit praktischen Techniken für KI-gestütztes Abhängigkeitsmanagement und paketübergreifendes Refactoring.

Voraussetzungen​

Bevor Sie beginnen, stellen Sie sicher, dass Sie Folgendes haben:

  • Cursor (neueste Version empfohlen) als IDE-Editor
  • Node.js 18 oder höher
  • pnpm global installiert (npm install -g pnpm)
  • Grundlegende Vertrautheit mit Paketmanagern und Workspaces
tipp

Das integrierte Terminal und die Multi-Root-Workspace-Unterstützung von Cursor machen es ideal für Monorepos. Öffnen Sie den Repository-Root in Cursor, damit die KI alle Pakete gleichzeitig sehen kann. Dies gibt dem Editor vollen Kontext für paketübergreifendes Refactoring und Abhängigkeitsanalyse.

Auswahl eines Monorepo-Tools​

Drei Tools dominieren die JavaScript- und TypeScript-Monorepo-Landschaft. Jedes hat unterschiedliche Stärken:

ToolAm besten fürWichtigste Stärke
pnpm workspacesKleine bis mittlere MonoreposSchnelle, speichereffiziente Installationen
TurborepoApp-fokussierte MonoreposEinfaches Task-Caching und parallele Ausführung
NxGroße, plugin-lastige MonoreposMächtige Codegenerierung und Abhängigkeitsgraph

Fragen Sie die KI von Cursor nach einer Empfehlung für Ihre Situation:

Ich habe ein Monorepo mit 2 Next.js-Apps, einer gemeinsamen
React-Komponentenbibliothek und 3 Utility-Paketen. Soll ich
Turborepo oder Nx verwenden? Vergleiche sie.

Cursor erklärt die Kompromisse und generiert eine Starter-Konfiguration für Ihr gewähltes Tool.

pnpm-Workspaces-Setup in Cursor​

pnpm-Workspaces sind die Grundlage der meisten modernen Monorepos aufgrund ihrer Geschwindigkeit und festverknüpften Speichereffizienz. Cursor hilft Ihnen, den Workspace zu definieren und die ersten Pakete zu erstellen.

Den Workspace-Root erstellen​

Öffnen Sie einen neuen Ordner in Cursor und bitten Sie die KI, einen pnpm-Workspace zu erstellen:

Erstelle ein pnpm-Workspace-Monorepo mit:
- Einer root package.json mit pnpm-Workspace-Konfiguration
- Einer pnpm-workspace.yaml, die apps/* und packages/* auflistet
- Einem gemeinsamen TypeScript-Konfigurationspaket
- Einer .npmrc mit Shared-Cache-Einstellungen

Cursor generiert die Root-Dateien:

# 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

Die ersten Pakete erstellen​

Bitten Sie Cursor, ein gemeinsames UI-Paket und eine Web-App zu generieren, die es verwendet:

Erstelle eine packages/ui React-Komponentenbibliothek und eine
apps/web Next.js-App. Die Web-App soll vom UI-Paket über das
workspace:*-Protokoll abhängen.

Cursor generiert die Paketstruktur:

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

Die 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"
}
}

Die apps/web/package.json referenziert das gemeinsame Paket über das Workspace-Protokoll:

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

Installieren Sie alles vom Root aus mit dem Terminal von Cursor:

pnpm install

pnpm verknüpft Abhängigkeiten fest, sodass die Installation schnell und speichereffizient ist.

warnung

Verwenden Sie immer das workspace:*-Protokoll (oder workspace:^), wenn Sie interne Pakete referenzieren. Wenn Sie eine Versionsnummer wie 1.0.0 anheften, versucht pnpm, das Paket aus der Registry abzurufen, anstatt das lokale Paket aufzulösen, was zu verwirrenden "package not found"-Fehlern bei der Installation führt.

Turborepo-Integration in Cursor​

Turborepo fügt Caching und parallele Task-Ausführung über pnpm-Workspaces hinzu. Cursor generiert die Pipeline-Konfiguration und hilft Ihnen, sie zu optimieren.

Turborepo zu einem bestehenden Workspace hinzufügen​

Bitten Sie Cursor, Turborepo zu Ihrem Monorepo hinzuzufügen:

Füge Turborepo zu meinem pnpm-Workspace hinzu. Erstelle eine
turbo.json mit Build-, Dev-, Lint- und Test-Pipelines. Konfiguriere
Build-Abhängigkeiten und Caching.

Cursor installiert die Abhängigkeit und generiert 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"]
}
}
}

Die dependsOn: ["^build"]-Direktive sagt Turborepo, die Abhängigkeiten eines Pakets zu bauen, bevor das Paket selbst gebaut wird, was für Monorepos kritisch ist, in denen Apps von gemeinsamen Bibliotheken abhängen.

Tasks mit Turbo ausführen​

Führen Sie Tasks über das gesamte Monorepo vom Terminal von Cursor aus:

# Alle Pakete in topologischer Reihenfolge bauen
pnpm turbo run build

# Dev-Server parallel ausführen
pnpm turbo run dev --parallel

# Auf ein einzelnes Paket und seine Abhängigen filtern
pnpm turbo run build --filter=@cursor-monorepo/web...

Das ...-Suffix bedeutet "dieses Paket und alles, was von ihm abhängt", was nützlich für die Auswirkungsanalyse ist, wenn Sie eine gemeinsame Bibliothek ändern.

tipp

Verwenden Sie das --filter-Flag mit dem ^-Präfix, um einen Task für ein Paket und seine Abhängigkeiten auszuführen. Zum Beispiel baut pnpm turbo run build --filter=^@cursor-monorepo/web nur die Pakete, die die Web-App benötigt, und überspringt irrelevante Arbeit. Dies ist unbezahlbar für schnelle lokale Feedback-Schleifen.

Remote-Caching konfigurieren​

Remote-Caching ermöglicht Ihrem Team, Build-Ergebnisse zu teilen. Bitten Sie Cursor, Vercel-Remote-Cache einzurichten:

Konfiguriere Turborepo-Remote-Caching für mein Monorepo. Generiere
das .nenv-Beispiel und erkläre, wie der Cache verlinkt wird.

Cursor erklärt die Schritte:

npx turbo login
npx turbo link

Fügen Sie einen turbo.json-Umgebungshinweis hinzu, damit Cache-Schlüssel die richtigen Variablen enthalten:

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

Nx-Integration in Cursor​

Nx ist ein mächtigeres Monorepo-Tool mit Code-Generatoren, einem Abhängigkeitsgraph und Plugin-Unterstützung für viele Frameworks. Cursor hilft Ihnen, Nx-Projekte zu erstellen und zu erweitern.

Einen Nx-Workspace erstellen​

Bitten Sie Cursor, einen Nx-Workspace zu erstellen:

Erstelle ein Nx-integriertes Monorepo mit:
- Einer React-App namens storefront
- Einer Node-API-App namens api
- Einer gemeinsamen Typen-Bibliothek
- pnpm als Paketmanager

Cursor führt das Gerüst aus und erklärt das Ergebnis:

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

Die resultierende Struktur:

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

Code mit Nx-Plugins generieren​

Nx-Plugins bieten Generatoren für konsistente Gerüsterstellung. Bitten Sie Cursor, eine React-Komponentenbibliothek zu generieren:

Generiere eine React-Bibliothek namens ui mit buildable true und
Storybook-Konfiguration mit dem @nx/react-Plugin.
npx nx g @nx/react:library ui --buildable --storybook --directory=libs/ui

Den Abhängigkeitsgraph visualisieren​

Nx liefert einen Graph-Visualisierer. Führen Sie ihn vom Terminal von Cursor aus:

npx nx graph

Dies öffnet einen interaktiven Graphen in Ihrem Browser, der zeigt, wie Pakete voneinander abhängen. Die KI von Cursor kann den Graphen auch als Text beschreiben, wenn Sie fragen:

Liste alle Pakete auf, die von libs/types abhängen und kaputtgehen
würden, wenn ich seinen Default-Export umbenenne.

Cursor liest die Workspace-Konfiguration und gibt eine Auswirkungsanalyse zurück, die vor dem Refactoring von gemeinsam genutztem Code unerlässlich ist.

warnung

Nx-integrierte Workspaces verwenden Pfad-Mapping in tsconfig.base.json für Imports. Wenn Sie eine neue Bibliothek hinzufügen, müssen Sie das paths-Mapping aktualisieren oder TypeScript kann den Import nicht auflösen. Die KI von Cursor kann fehlende Pfad-Mappings erkennen und die Korrektur vorschlagen, wenn Sie "Cannot find module"-Fehler sehen.

KI-gestütztes Abhängigkeitsmanagement​

Abhängigkeiten über ein Monorepo hinweg konsistent zu halten, ist eine der schwierigsten Wartungsaufgaben. Die KI von Cursor glänzt hierbei.

Versionskonflikte auditeren​

Bitten Sie Cursor, Abhängigkeitskonflikte zu finden:

Scanne alle package.json-Dateien in meinem Monorepo und melde
Abhängigkeiten, die inkonsistente Versionen über Pakete hinweg haben.
Schlage eine einzige angeheftete Version für jede vor.

Cursor liest jede package.json, listet Konflikte auf und kann ein Skript generieren, um sie anzugleichen:

# react überall auf 18.2.0 angleichen

Ungenutzte Abhängigkeiten erkennen​

Cursor kann Pakete erkennen, die in package.json deklariert, aber nie importiert werden. Fragen Sie:

Finde ungenutzte Abhängigkeiten im apps/web-Paket, indem du die
Imports über alle Quelldateien überprüfst.

Cursor meldet die ungenutzten Einträge und schlägt den Entfernungsbefehl vor:

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

Gemeinsame Dev-Abhängigkeiten verwalten​

Heben Sie gemeinsame Entwicklungstools (ESLint, Prettier, TypeScript) in den Workspace-Root, um Versionsdrift zu vermeiden. Cursor generiert ein gemeinsames Konfigurationspaket:

Erstelle ein packages/config-Paket, das gemeinsame ESLint-,
TypeScript- und Prettier-Konfigurationen exportiert, damit andere
Pakete sie erweitern können.
// 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'] }],
},
};

Andere Pakete erweitern die gemeinsame Konfiguration:

{
"eslintConfig": { "extends": "@cursor-monorepo/config/eslint" }
}
tipp

Verwenden Sie pnpm's catalog-Funktion (oder Renovate), um Versionsnummern an einem zentralen Ort zu bündeln. Bitten Sie Cursor: "Richte einen pnpm-Katalog für alle gemeinsamen Abhängigkeitsversionen ein," und es wird den pnpm-workspace.yaml-Katalogblock erstellen, sodass ein einzelner Versions-Update sich überall automatisch fortpflanzt.

Paketübergreifendes Refactoring mit Cursor​

Das Refactoring einer gemeinsamen API betrifft jeden Verbraucher. Die Codebase-Indizierung von Cursor ermöglicht es der KI, Verwendungen über das gesamte Monorepo hinweg zu verfolgen, was große Refactors sicher macht.

Einen gemeinsamen Export umbenennen​

Angenommen, Sie möchten die Button-Komponente in ActionButton in packages/ui umbenennen. Bitten Sie den Agent von Cursor:

Benenne die Button-Komponente im gesamten Monorepo in ActionButton
um. Aktualisiere den Export, den Typ, alle Imports und die
Storybook-Stories. Führe den Build aus, um zu überprüfen, dass
nichts kaputt ist.

Cursor führt die Mehrfachdatei-Bearbeitung in einem Durchgang aus:

// 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')} />;
}

Eine gemeinsame Utility extrahieren​

Wenn Sie duplizierte Logik über Pakete hinweg finden, bitten Sie Cursor, sie zu extrahieren:

Extrahiere die Datumsformatierungslogik, die in apps/web und
apps/api dupliziert ist, in ein neues gemeinsames Paket namens
@cursor-monorepo/format. Aktualisiere alle Aufrufstellen, um aus
dem neuen Paket zu importieren.

Cursor erstellt das Paket, verschiebt den Code, aktualisiert Imports und führt die betroffenen Builds aus, um den Erfolg zu bestätigen.

warnung

Führen Sie nach einem paketübergreifenden Refactoring immer die vollständige Test-Suite und die Typprüfung für den gesamten Workspace aus. Ein einzelner verpasster Import kann isoliert kompilieren, aber fehlschlagen, wenn Pakete zusammengesetzt werden. Führen Sie pnpm -r run build && pnpm -r run test vom Root aus, um diese Probleme früh zu erkennen.

Workspace-Konfiguration und Tooling​

Konsistentes Tooling über Pakete hinweg hält ein Monorepo gesund. Cursor kann gemeinsame Konfigurationen für TypeScript, ESLint und CI generieren.

Gemeinsame TypeScript-Konfiguration​

Erstelle eine gemeinsame tsconfig-Basis unter packages/config/tsconfig/base.json
mit Strict Mode, Pfad-Aliasen und modernen Lib-Einstellungen.
{
"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
}
}

Jedes Paket erweitert sie:

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

CI-Pipeline mit GitHub Actions​

Bitten Sie Cursor, eine CI-Pipeline zu generieren, die Turborepo-Caching nutzt:

Erstelle einen GitHub-Actions-Workflow, der:
- pnpm und Node installiert
- Den pnpm-Store-Cache wiederherstellt
- turbo run lint build test mit Caching ausführt
- Nur betroffene Tasks bei Pull Requests ausführt
# .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

Zusammenfassung der Best Practices​

Beachten Sie diese Prinzipien bei der Verwaltung eines Monorepos in Cursor:

  • Öffnen Sie den Workspace-Root, damit Cursor jedes Paket für paketübergreifenden Kontext sehen kann.
  • Verwenden Sie das Workspace-Protokoll (workspace:*) für interne Paketreferenzen.
  • Heben Sie gemeinsame Dev-Tools in ein Konfigurationspaket, um Versionsdrift zu vermeiden.
  • Nutzen Sie Task-Caching mit Turborepo oder Nx, um CI schnell zu halten.
  • Führen Sie Auswirkungsanalysen vor dem Refactoring gemeinsamer APIs durch.
  • Zentralisieren Sie Versionen mit pnpm-Katalogen oder Renovate.

Durch die Kombination eines soliden Monorepo-Tools mit dem KI-gestützten Codebase-Verständnis von Cursor können Sie gemeinsamen Code zuversichtlich refactoren, Abhängigkeiten angleichen und konsistentes Tooling über viele Pakete hinweg ausliefern. Beschreiben Sie Ihre Absicht klar, lassen Sie Cursor die Boilerplate und die paketübergreifenden Bearbeitungen übernehmen, und überprüfen Sie die generierten Diffs vor dem Committen.