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.
Czego się nauczysz
Dział zatytułowany „Czego się nauczysz”- 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ń
Przepływ pracy
Dział zatytułowany „Przepływ pracy”Krok 1: Oceń aktualny stan
Dział zatytułowany „Krok 1: Oceń aktualny stan”Przed modernizacją czegokolwiek zrozum, z czym pracujesz. Użyj CLI do szybkiej oceny:
Krok 2: Skonfiguruj infrastrukturę migracji
Dział zatytułowany „Krok 2: Skonfiguruj infrastrukturę migracji”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 work2. Configure the build to handle both .js and .ts files3. Add @types packages for our dependencies (express, react, etc.)4. Update ESLint to handle both JS and TS files5. Create a tsconfig.strict.json that new TS files should target6. 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.Krok 3: Migruj w równoległych partiach
Dział zatytułowany „Krok 3: Migruj w równoległych partiach”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)
Migrate all files in src/utils/ from JavaScript to TypeScript:
For each file:1. Rename from .js to .ts2. Add type annotations to all function parameters and return types3. Replace require() with import statements4. Replace module.exports with named exports5. Replace callbacks with async/await where applicable6. Fix any type errors reported by tsc
Do NOT change the function signatures or behavior.Run the test suite after each file migration.If a test fails, fix the migration (not the test).Update scripts/migration-progress.json with the new counts.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/)
Krok 4: Użyj zadań w chmurze dla trudnych migracji
Dział zatytułowany „Krok 4: Użyj zadań w chmurze dla trudnych migracji”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.
codex cloud exec --env migration-env --attempts 3 "Migrate src/services/legacy-payment-processor.js to TypeScript..."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.
Krok 5: Śledź postęp z automatyzacjami
Dział zatytułowany „Krok 5: Śledź postęp z automatyzacjami”Skonfiguruj cotygodniową automatyzację mierzącą postęp migracji i identyfikującą następną partię:
Migracja komponentów React
Dział zatytułowany „Migracja komponentów React”Dla modernizacji specyficznej dla React (komponenty klasowe do funkcyjnych z hookami) wzorzec jest ten sam, ale prompty są specyficzne:
Migrate src/components/Dashboard.jsx from a class component to a functional component with hooks:
1. Convert the class to a function component2. Replace this.state and this.setState with useState hooks3. Replace componentDidMount, componentDidUpdate, componentWillUnmount with useEffect4. Replace class methods with const functions or useCallback where appropriate5. Add TypeScript types for props, state, and any callbacks6. Rename from .jsx to .tsx
Preserve the exact same rendering behavior and prop interface.Run the component tests after migration. The tests should pass without changes.If a test references class-specific APIs (e.g., wrapper.instance()), update the test to use Testing Library patterns.Kiedy to nie działa
Dział zatytułowany „Kiedy to nie działa”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.