TypeScript Isolated Declarations: Monorepo-Geschwindigkeit steigern
Monorepo-Builds verlangsamen sich oft dadurch, wie TypeScript mit Deklarationsdateien umgeht. Standardmäßig analysiert TypeScript jede Import-Kette, bevor es eine einzige .d.ts-Datei erstellt. Dies führt zu einer langen Warteschlange, in der Pakete aufeinander warten müssen.
Dies lässt sich mit dem --isolatedDeclarations-Flag beheben.
Dieses Flag ermöglicht parallele Builds. Anstatt auf Abhängigkeiten zu warten, generiert jedes Paket seine eigenen Deklarationen unabhängig. Teams verzeichnen eine Steigerung der Build-Geschwindigkeit um das 3- bis 15-fache.
The Problem: TypeScript leitet Typen normalerweise über Modulgrenzen hinweg ab. Wenn Paket A von Paket B abhängt, muss der Compiler B vollständig auflösen, bevor er mit A beginnen kann. In einem großen Monorepo verharren die meisten Pakete im Leerlauf, während der Compiler sie nacheinander abarbeitet.
The Solution:
Das --isolatedDeclarations-Flag ändert die Regeln. Es erfordert, dass Sie explizite Typannotationen für alles schreiben, was Sie exportieren.
The Tradeoff: Ihr Code wird mehr Text enthalten. Sie müssen Funktionen manuell Rückgabetypen und Konstanten manuell Typen zuweisen. Sie können sich nicht darauf verlassen, dass der Compiler diese Typen aus Ihrem Code ableitet.
The Result: Da jeder Export einen klaren Typ hat, muss der Compiler nicht in andere Pakete schauen, um sie zu verstehen. Er kann jedes Paket gleichzeitig verarbeiten.
Real World Results:
- Ein Monorepo mit 18 Paketen reduzierte die Build-Zeiten von 47 Sekunden auf 3,2 Sekunden.
- Ein Monorepo mit 32 Paketen erzielte eine 8-fache Beschleunigung in CI-Pipelines.
- Die Performance skaliert mit Ihren CPU-Kernen. Mehr Kerne bedeuten, dass mehr Pakete gleichzeitig gebaut werden können.
How to Migrate:
- Aktivieren Sie das Flag in Ihrer
tsconfig.jsonim Root-Verzeichnis und in jeder Paket-Konfiguration. - Verwenden Sie das
"composite"-Flag, um Project References zu ermöglichen. - Fügen Sie exportierten Funktionen explizite Rückgabetypen hinzu:
// Vorher export function add(a: number, b: number) { return a + b; }
// Nachher export function add(a: number, b: number): number { return a + b; }
- Fügen Sie exportierten Konstanten explizite Typen hinzu:
// Vorher export const SETTINGS = { port: 3000 };
// Nachher export const SETTINGS: { port: number } = { port: 3000 };
Wenn Sie diese Typen nicht hinzufügen, wird der Compiler Fehler ausgeben. Dies stellt sicher, dass Ihre Typen deterministisch und schnell sind.
