Monorepository mit TypeScript: Code-Organisation in der Praxis
\n\nIn der modernen Webentwicklung, insbesondere bei der Arbeit mit TypeScript, stehen Entwickler oft vor dem Dilemma: den gesamten Code in einem Repository (Monorepository) zu speichern oder ihn auf viele kleine Repositories (Polyrepository) aufzuteilen. Für mittlere und große Projekte, bei denen Wiederverwendbarkeit von Code und eine einheitliche Konfiguration wichtig sind, wird das Monorepository zum De-facto-Standard. In diesem Artikel werden wir uns ansehen, wie man ein Monorepository mit TypeScript richtig organisiert, angefangen bei der grundlegenden Struktur bis hin zu fortgeschrittenen Techniken.
\n\nWas ist ein Monorepository und warum wird es benötigt?
\n\nEin Monorepository ist ein Ansatz, bei dem der Code mehrerer Projekte (Pakete, Bibliotheken, Anwendungen) in einem einzigen Repository gespeichert wird. Im Kontext von TypeScript ist dies besonders praktisch, da es Folgendes ermöglicht:
\n\n- \n
- Wiederverwendung von Typen und Schnittstellen zwischen verschiedenen Teilen des Systems ohne Veröffentlichung in npm. \n
- Vereinfachung des Refactorings: Eine Änderung in einem Paket wird automatisch in allen abhängigen Paketen validiert. \n
- Einheitliche Konfiguration für Linter, Formatierer und Builder. \n
- Vereinfachung von CI/CD: Ein Repository – eine Pipeline. \n
Zu den beliebten Tools für die Arbeit mit Monorepositories in TypeScript gehören Nx, Turborepo und npm/yarn/pnpm workspaces. Wir werden den Ansatz mit pnpm workspaces und TypeScript Project References betrachten, da dies eine minimale und flexible Kombination ist.
\n\nStruktur des Monorepositorys: Grundlegende Einrichtung
\n\nLassen Sie uns eine typische Struktur eines Monorepositorys für ein TypeScript-Projekt erstellen. Angenommen, wir haben drei Pakete: core (allgemeine Typen und Hilfsfunktionen), server (Backend) und web (Frontend).
1. Root-Konfiguration
\n\nBeginnen wir mit dem Stammverzeichnis des Projekts. Erstellen wir eine package.json-Datei mit Workspace:
{\n "name": "my-monorepo",\n "private": true,\n "workspaces": [\n "packages/*"\n ],\n "scripts": {\n "build": "tsc -b",\n "clean": "tsc -b --clean",\n "lint": "eslint packages/*/src"\n }\n}\n\n\nDann konfigurieren wir die root tsconfig.json. Wir verwenden Project References – dies ist eine Schlüsselfunktion von TypeScript für Monorepositories:
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "strict": true,\n "composite": true,\n "declaration": true,\n "declarationMap": true,\n "sourceMap": true,\n "outDir": "./dist",\n "rootDir": ".",\n "skipLibCheck": true\n },\n "references": [\n { "path": "./packages/core" },\n { "path": "./packages/server" },\n { "path": "./packages/web" }\n ]\n}\n\n\nWichtig: Die Option composite: true ist für Pakete obligatorisch, auf die andere Pakete verweisen. Sie aktiviert die inkrementelle Kompilierung und die Generierung von .d.ts-Dateien.
2. Einrichtung des core-Pakets
\n\nWechseln wir zu packages/core. Erstellen wir package.json:
{\n "name": "@my/core",\n "version": "1.0.0",\n "main": "dist/index.js",\n "types": "dist/index.d.ts",\n "scripts": {\n "build": "tsc -b"\n }\n}\n\n\nUnd die tsconfig.json für dieses Paket:
{\n "extends": "../../tsconfig.json",\n "compilerOptions": {\n "outDir": "./dist",\n "rootDir": "./src"\n },\n "include": ["src"]\n}\n\n\nErstellen wir ein einfaches Modul src/index.ts:
export interface User {\n id: string;\n name: string;\n email: string;\n}\n\nexport function greet(user: User): string {\n return `Hello, ${user.name}!`;\n}\n\n\nJetzt ist das Paket
Blogs
Buchempfehlungen
Lesen Sie auch
Logging in Swift-Anwendungen: Best Practices für Anfänger
Mikroservices mit Kotlin: Architektur und Praxis
Reverse for in Rust: Wie man als Anfänger nicht in die Falle tappt
C++ in realen Projekten: Anwendungsfälle von Google bis zu Spielen
Refactoring von JavaScript-Code: Wann und wie man das Projekt nicht kaputt macht