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

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
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:
| Tool | Am besten für | Wichtigste Stärke |
|---|---|---|
| pnpm workspaces | Kleine bis mittlere Monorepos | Schnelle, speichereffiziente Installationen |
| Turborepo | App-fokussierte Monorepos | Einfaches Task-Caching und parallele Ausführung |
| Nx | Große, plugin-lastige Monorepos | Mä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.
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.
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.
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
pnpm -r exec pnpm add [email protected] [email protected]
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" }
}
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.
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.