Upgrades

Wie du eine neue Flow-Version einspielst – der Migrationsleitfaden für Breaking Changes, die Codemod-CLI und was direkt nach einem Release zu beachten ist.

Migration bei einer Breaking Change

Jede Änderung, die eine Anpassung in deinem Code erfordert, steht mit Vorher-Nachher-Beispiel im Migrationsleitfaden des betroffenen Packages:

Die Einträge sind nach Version absteigend sortiert und nennen jeweils die Version, ab der die Änderung greift. Suche die Version, von der du kommst, und arbeite dich nach oben durch. Was dabei überhaupt als Breaking Change zählt und eine neue Major-Version erzwingt, beschreibt Versionierung & Stabilität.

Nutze die Codemod-CLI

Ein Befehl hebt alle Flow-Abhängigkeiten auf die Zielversion, installiert und führt den Codemod jeder Migration bis zu dieser Version aus:

Ohne Argument geht es auf die nächste Minor innerhalb deiner Major. upgrade patch bleibt auf deiner Minor, upgrade major überquert eine Major-Grenze, und eine exakte Version oder ein Dist-Tag (next) gehen genau dorthin.

Der Befehl ändert Dateien direkt und bricht auf einem unsauberen Git-Stand ab.

Der Befehl kennt keine untere Grenze: er listet auch Migrationen, die vor deiner aktuellen Version erschienen sind. Nichts hält fest, welche davon dein Projekt schon durchgeführt hat – und ein zweiter Durchlauf eines Codemods ändert nichts.

Ein Codemod, der durchgelaufen ist, ist allerdings kein Beweis: jeder Codemod ist bewusst eng gefasst und lässt liegen, was er aus dem Code nicht sicher entscheiden kann – ein gespreadetes Prop, eine Component, die über einen eigenen Wrapper re-exportiert wird, ein dynamischer Zugriff. Einen Fehler meldet er dafür nicht. Prüfe nach einem Upgrade deshalb auch die Migrationen mit Codemod am Code nach, nicht nur die ohne.

Er ersetzt den Migrationsleitfaden nicht: die meisten Einträge haben keinen Codemod. Welche das für deinen Bereich sind, listet der Befehl am Ende auf – oder vorab, ohne etwas zu verändern, mit list und derselben Revision:

list ohne Argument zeigt den gesamten Katalog, offline. Mit einer Revision liest es dieselbe Version aus deinem package.json und zeigt genau den Bereich, den upgrade mit dieser Revision anfassen würde – ein echter Trockenlauf.

Einen einzelnen Codemod führst du über seine ID aus:

Lass einen Agenten das Upgrade machen

Was die CLI offen lässt, kann ein Coding-Agent übernehmen: die Migrationen ohne Codemod – das sind die meisten – und die Stellen, die ein Codemod übersprungen hat. list --json liefert ihm dafür pro Migration das Feld apply: die Anweisung, was zu ändern ist, knapp genug für einen Katalog und präzise genug zum Ausführen.

Kopiere den folgenden Prompt in deinen Agenten. Er sucht zuerst, wo Flow überhaupt deklariert ist – in einem Monorepo ist das meist mehr als ein Package, und list wie upgrade lesen immer nur die package.json des Verzeichnisses, in dem sie laufen. Dann klärt er auf, welche Zielversionen zur Wahl stehen und was jede davon an Arbeit bedeutet, und fragt dich, welche es sein soll. Danach geht er jede Migration im Bereich am Code nach – auch die mit Codemod – und ändert nur, wo er das alte Muster wirklich findet.

Was dabei offen bleibt, gibt er dir nicht als Hausaufgabe zurück. Genau die Punkte, die eine Entscheidung brauchen, sind die, bei denen er den Diff gelesen hat und du nicht – deshalb legt er sie dir gesammelt vor, jeweils mit den Optionen und einer Empfehlung, setzt deine Antwort um und lässt die Checks erneut laufen. Das wiederholt sich, bis nichts mehr offen ist. Er hört vorher nur auf, wenn etwas wirklich nicht hier entschieden werden kann – eine Design-Entscheidung, eine Freigabe, ein Zugang – und sagt dann, worauf es wartet und wer es tun muss.

Der Prompt ist englisch, weil alles, worauf er zeigt, englisch ist: die CLI-Ausgabe, die apply-Felder und der Migrationsleitfaden.

Zwei Dinge, die der Prompt bewusst nicht tut: Er lässt den Agenten nicht auf einem unsauberen Git-Stand starten, damit ein missglückter Lauf ein git checkout bleibt. Und er lässt ihn nichts an deinen peerDependencies ändern – was deine eigenen Consumer installieren dürfen, ist deine Entscheidung.

Optional: erzähl uns, was nicht getragen hat

Ganz unabhängig vom Upgrade: der folgende Prompt ist ein zweiter, eigener Baustein. Du kopierst ihn – wenn du magst – direkt nach dem Upgrade in dieselbe Session. Der Agent hat den Lauf dann noch im Kontext und schreibt daraus einen Bericht auf zwei Ebenen. Nicht kopieren ist die Absage; am Upgrade ändert das nichts.

Der Prompt selbst. Ein Schritt in der falschen Reihenfolge. Eine Annahme, die auf dein Projekt nicht zutrifft. Eine Stelle, an der der Agent raten musste oder zwei Anweisungen sich widersprachen. Eine Situation, zu der der Prompt schweigt. Eine Anweisung, die Arbeit gekostet und nichts geändert hat.

Die einzelne Migration. Ein apply, das ohne Raten nicht ausführbar war. Eine Stelle, die ein Codemod liegen gelassen hat, obwohl er sie hätte entscheiden können. Eine Migration ohne Codemod, die mechanisch entscheidbar wäre. Ein apply, das eine Umbenennung beschreibt, obwohl sich auch die Signatur geändert hat. Ein Codemod, der abgestürzt ist. Und der wertvollste Fall: ein Bruch, den deine Checks gefunden haben und für den es gar keinen Katalogeintrag gibt.

Beide Ebenen sehen wir sonst nicht. Ob eine Migration verständlich beschrieben ist und ob der Upgrade-Prompt trägt, zeigt sich erst an einer echten Codebase – nicht an unserer. Ein Bericht als Issue hilft uns deshalb wirklich weiter: er fließt in den Katalog und in den Prompt zurück, und das nächste Upgrade ist für alle etwas weniger Handarbeit. Ein Paste genügt, und eine Antwort schuldest du niemandem.

Der Agent reicht ihn nicht selbst ein. Er legt ihn dir vor und sagt dir, was du damit tun kannst – du entscheidest, was rausgeht. Code-Beispiele reduziert er auf die kleinste anonymisierte Form, aber prüfen musst du das selbst.

Deprecation-Warnungen sind der Vorlauf

Wird ein Pfad deprecated, bleibt er funktionsfähig und meldet sich zur Laufzeit per console.warn. Diese Warnungen sind die Vorwarnzeit vor der nächsten Major-Version – behandle sie als Aufgabenliste, nicht als Rauschen. Um sie zentral einzusammeln, etwa im Error-Tracking, umschließe deine Anwendung mit einem DeprecationWarningProvider und gib ihm einen onWarning-Handler:


Direkt nach einem Release

Ein Release veröffentlicht die Packages nacheinander, nicht gleichzeitig. Für einige Minuten liegt in der npm-Registry deshalb für die schon veröffentlichten Packages die neue Version, für die restlichen noch die alte. Beim Release 1.0.6 lagen zwischen dem ersten und dem letzten Package rund 25 Minuten.

Du triffst dieses Fenster leicht, denn ein Update betrifft immer mehrere Packages: alle @mittwald/flow-*-Packages teilen sich eine gemeinsame Version, und @mittwald/flow-react-components fordert @mittwald/flow-icons-pro als Peer-Dependency in exakt derselben Version. Ziehst du in diesem Fenster alle Flow-Abhängigkeiten auf die neue Version, schlägt die Installation für das Package fehl, das noch nicht dran war:

pnpm meldet dasselbe als ERR_PNPM_NO_MATCHING_VERSION.

Das ist keine Lücke im Release: sobald der Release-Lauf durch ist, haben alle Packages dieselbe Version. Direkt nach einem Release ist dieser Fehler fast immer das Veröffentlichungsfenster und nichts anderes.

Auf dieser Seite