Zum Inhalt springen

Modernisierung eines alten Frontends

Kein TypeScript. Kein Linter. Kein Sentry. 170 Standorte nutzen es täglich.

Ein untypisiertes, nicht überwachtes altes Frontend schrittweise modernisieren, während das Produkt für bestehende Nutzer verfügbar bleibt.

5 Min. LesezeitVon

Die übernommenen Einschränkungen waren real

Das übernommene CRA-Frontend bestand aus reinem JavaScript ohne TypeScript, ESLint, Prettier oder Sentry und besaß weder ein wiederverwendbares Komponentensystem noch eine schlüssige Funktionsstruktur. Es enthielt mehr als 5.000 Zeilen reines CSS, durch Inline-Stile überschriebene Tailwind-Klassen, kopierte Seiten und eine flache Verzeichnisstruktur.

Die Probleme verstärkten sich gegenseitig. API-Änderungen erreichten den Browser ohne Rückmeldung des Compilers. Kopierte Bildschirme wiederholten dieselben Gestaltungsfehler. Produktivfehler wurden meist erst durch Nutzermeldungen bekannt, weil es keinen Überwachungsweg gab.

Die Wartungskosten wirkten sich auf die Nutzer aus

Die Anwendung bediente weiterhin täglich 170 Kundenstandorte. Wir stellten V1 weder direkt um noch warteten wir auf einen vollständigen Ersatz. Die alten Routen liefen weiter, und jede neue V2-Route musste die neuen Standards erfüllen.

So erhielt das Team eine einfache Regel: Die alten Konventionen nicht ausweiten. Die Zuständigkeit verschieben, wenn eine Route neu gebaut wird, und den alten Weg entfernen, sobald der neue produktiv läuft.

Eine typisierte Grenze schaffen

Next.js 15 und TypeScript bildeten die neue Grenze. Neue Routen nutzten typisierte Routendefinitionen, generierte API-Clients, gemeinsam genutztes Fetch-Verhalten und funktionsbezogene Komponenten. Das Team konvertierte nicht zuerst jede alte Datei; es fügte keine neuen untypisierten Bereiche mehr hinzu und verschob die Zuständigkeit nach V2, sobald die Arbeit eine Route erreichte.

  • TypeScript und typisierte Routen machten Navigationsfehler und Fehler in der API-Struktur während der Entwicklung sichtbar.
  • Generierte Clients und gemeinsam genutztes Fetch-Verhalten ersetzten verstreute Anfragekonventionen.
  • Funktionsbezogene Ordner gaben Routen, Hooks, Schemas und Tests eindeutige Verantwortliche.
  • Wiederverwendbare Grundbausteine ersetzten Kopien auf Seitenebene für wiederkehrende Interaktionsmuster.

Rückkopplungsschleifen einführen, bevor alle Ansichten migriert werden

Die Modernisierung änderte auch, wie Fehler erkannt und Änderungen zugelassen wurden. Sentry ergänzte Berichte für Client, Server und Edge sowie Fehlergrenzen der Anwendung. Unit- und Browserarbeitsabläufe erhielten eindeutig benannte erforderliche Gates, während verhaltensbezogene Tests risikoreiche Abläufe wie Investor Intake abdeckten.

Diese Kontrollen reparierten V1 nicht automatisch. Sie machten jede V2-Route beobachtbar und prüfbar, bevor diese mehr Verantwortung im Produktivbetrieb übernahm.

Eine neue Grenze um das alte Produkt bauen

V2 übernahm die globale Anwendungsoberfläche, Authentifizierung und jede neu migrierte Funktion. CRA verblieb nur für die weiterhin von ihm verantworteten Routen in einem einzelnen iframe. Der begleitende Migrationsartikel behandelt die postMessage-, SSO- und Routingbrücke im Detail.

Für diesen Artikel ist die Zuständigkeit entscheidend: An der V2-Grenze galten neue Standards, und jede abgeschlossene Migration verringerte den davon ausgenommenen Codeumfang.

Zuständigkeiten während des Übergangs sichtbar machen

Die Zuständigkeit wurde während des Übergangs ausdrücklich erfasst. Navbar, Topbar, Settings, Investor Intake, Authentication und Twilio wechselten zu V2. Home, Genius Mode, Deals und Buyers blieben in V1, bis ihr Ersatz bereitstand. Kundenstandorte wurden in kontrollierten Gruppen umgestellt, statt alle unfertigen Oberflächen gleichzeitig zu erhalten.

Diese Bestandsaufnahme verhinderte, dass die Neuentwicklung zu einem undefinierten Parallelprojekt wurde. Eine Funktion war entweder weiterhin V1 zugeordnet, wurde über die Kompatibilitätsgrenze bereitgestellt oder war nativ in V2 umgesetzt.

Modernisierung ist eine Abfolge, kein einzelnes Ereignis

Beim endgültigen Wechsel wurden iframe, alte generierte Clients und Brückencode entfernt. Danach folgte die Bereinigung überholter Routen, Tests, Authentifizierungs-Guards, gemeinsam genutzter Dialerlogik und Komponentenstruktur. Die Modernisierung war erst abgeschlossen, als die vorübergehende Grenze gelöscht werden konnte.

  • Messen Sie Fortschritt nicht an der Anzahl neu erstellter Frameworkdateien.
  • Messen Sie, welche produktiven Zuständigkeiten verschoben wurden und welche Kompatibilitätswege entfernt werden können.
  • Halten Sie neuen Code innerhalb der neuen Standards, statt auf eine perfekte Umstellung der gesamten Codebasis zu warten.
  • Löschen Sie vorübergehende Migrationsinfrastruktur, nachdem die letzte davon abhängige Oberfläche migriert wurde.