Przejdź do głównej zawartości

Modernizacja starszego kodu na skalę

Twoja baza kodu ma 80 000 linii JavaScript z 2018 roku — bez TypeScript, callbacki zamiast async/await, komponenty klasowe zamiast hooków i zestaw testów pokrywający 15% kodu. Zarząd chce modernizacji “bez żadnych regresji produkcyjnych”. Ostatni zespół, który próbował przepisania big-bang, spędził sześć miesięcy i nie dostarczył nic. Codex pozwala ci modernizować inkrementalnie: migruj plik po pliku w równoległych worktree, waliduj testami na każdym kroku i używaj zadań w chmurze z wieloma próbami, aby znaleźć najlepszą strategię migracji dla trudnych modułów.

  • Etapowa strategia modernizacji utrzymująca aplikację w stanie wdrażalnym na każdym etapie
  • Prompty do typowych migracji: JS do TS, callbacki do async/await, komponenty klasowe do funkcyjnych
  • Wzorce zadań w chmurze z podejściem best-of-N dla trudnych decyzji migracyjnych
  • Przepis na automatyzację śledzenia postępu migracji co tydzień

Przed modernizacją czegokolwiek zrozum, z czym pracujesz. Użyj CLI do szybkiej oceny:

Zanim równoległe agenty zaczną migrować pliki, skonfiguruj narzędzia umożliwiające migrację. Zrób to w trybie Local:

Set up the infrastructure for incremental TypeScript migration:
1. Add tsconfig.json with allowJs: true so existing JS files continue to work
2. Configure the build to handle both .js and .ts files
3. Add @types packages for our dependencies (express, react, etc.)
4. Update ESLint to handle both JS and TS files
5. Create a tsconfig.strict.json that new TS files should target
6. Update CI to run type-check on .ts files only (do not fail on .js files)
7. Add a migration tracking file (scripts/migration-progress.json) that counts JS vs TS files per directory
Run the existing test suite to confirm nothing broke.

Podziel bazę kodu na partie migracyjne według katalogów. Każda partia działa we własnym worktree. Kluczowa zasada: każda partia musi zostawić aplikację w stanie wdrażalnym.

Worktree 1: Warstwa narzędzi (najniższe ryzyko)

Worktree 2: Warstwa bazodanowa

Migrate all files in src/lib/db/ from JavaScript to TypeScript.
Same approach as the utility migration: rename, add types, convert imports, replace callbacks with async/await.
Additional requirements for database files:
- Type the query results using Drizzle's inferred types
- Replace raw SQL strings with Drizzle query builder calls where possible
- Add return type annotations that match the actual database response shapes
Run tests after each file. Fix any type errors.

Worktree 3: Warstwa serwisów (ten sam wzorzec, src/services/)

Worktree 4: Handlery tras (ten sam wzorzec, src/routes/)

Niektóre pliki są trudniejsze do migracji niż inne — głęboko zagnieżdżone callbacki, złożone hierarchie klas lub moduły z niejawnym stanem globalnym. Dla nich użyj zadań w chmurze z --attempts, aby eksplorować różne strategie migracji.

Przekaż pełną treść promptu z powyższego Aside z poradą jako opis zadania (skrócony tutaj dla czytelności):

Okno terminala
codex cloud exec --env migration-env --attempts 3 "Migrate src/services/legacy-payment-processor.js to TypeScript: flatten the nested callbacks to async/await, make the global config dependency an explicit constructor parameter, add comprehensive types, add tests, and keep the public interface stable."

Z trzema próbami Codex eksploruje różne podejścia do spłaszczania callbacków i restrukturyzacji klas. Porównaj wyniki: jedna próba może zachować hierarchię klas z generykami TypeScript; inna może spłaszczyć do czystych funkcji; trzecia może użyć podejścia hybrydowego. Wybierz to, które jest najczystsze i najłatwiejsze w utrzymaniu.

Skonfiguruj cotygodniową automatyzację mierzącą postęp migracji i identyfikującą następną partię:

Dla modernizacji specyficznej dla React (komponenty klasowe do funkcyjnych z hookami) wzorzec jest ten sam, ale prompty są specyficzne:

Zmigrowany plik psuje niezmigrowany plik, który go importuje. Zmiana z module.exports na named exports może złamać konsumentów require(). Włącz esModuleInterop w tsconfig.json i powiedz Codex: “When converting exports, ensure backward compatibility with CommonJS consumers. If any .js file imports from this module, verify the import still works after migration.”

Błędy typów kaskadowo rozchodzą się po bazie kodu. Gdy dodajesz typy do funkcji narzędziowej, każdy jej wywołujący może teraz mieć błąd typów. Użyj allowJs: true i sprawdzaj typy tylko w plikach .ts na początku. W miarę migracji kolejnych plików pokrycie sprawdzania typów naturalnie się rozszerza.

Zadanie w chmurze migruje wobec złej bazy. Jeśli twoja gałąź z infrastrukturą migracji nie została scalona do domyślnej gałęzi środowiska chmurowego, zadania w chmurze nie zobaczą tsconfig.json ani pakietów typów. Zaktualizuj mapę repozytoriów środowiska chmurowego, aby używała gałęzi migracji, lub scal zmiany infrastrukturalne do main najpierw.

Migracja wprowadza subtelne zmiany zachowania. Konwersja callbacków na async/await może zmienić kolejność wykonywania. Konwersja komponentów klasowych na hooki może zmienić zachowanie re-renderów. Zawsze uwzględniaj “verify identical behavior” w swoim prompcie i uruchamiaj istniejący zestaw testów — nie polegaj tylko na nowych testach.