Przejdź do głównej zawartości

Workflow migracji frameworków w Cursor

Twoja aplikacja React używa komponentów klasowych, Redux z connect(), React Router v5 i niestandardowego builda Webpack. Zespół chce przejść na komponenty funkcyjne z hookami, Zustand do zarządzania stanem, React Router v7 i Vite. Jest 180 komponentów, 45 kontenerów podłączonych do Redux i 30 definicji tras. Pełny rewrite zajmie miesiące i zatrzyma rozwój nowych funkcji. Stopniowa migracja pozwala dalej dostarczać funkcjonalności podczas modernizacji — ale potrzebujesz systematycznego podejścia, aby nie skończyć z bazą kodu, która na zawsze jest w połowie starych wzorców i w połowie nowych.

Migracje frameworków to jeden z najsilniejszych przypadków użycia Cursor. Transformacje są mechaniczne (konwersja składni klas na funkcje, zamiana jednego API na inne), wzorce są dobrze udokumentowane, a wolumen jest na tyle duży, że wsparcie AI zwraca się wielokrotnie. Wyzwanie nie polega na pojedynczej transformacji — polega na orkiestracji 180 takich transformacji bez psucia czegokolwiek.

  • Workflow planowania, który mapuje zakres migracji przed zmianą jakiegokolwiek kodu
  • Prompty do automatycznej transformacji plik po pliku z walidacją
  • Strategia strangler fig, która pozwala migrować przyrostowo bez “wielkiego wybuchu”
  • Techniki obsługi najtrudniejszych migracji (zarządzanie stanem, routing, narzędzia budowania)
  • Reguły projektu, które zapobiegają mieszaniu starych i nowych wzorców w nowym kodzie

Każda migracja zaczyna się od inwentaryzacji. Musisz wiedzieć dokładnie, co migrujesz, ile plików jest dotkniętych i jakie transformacje są potrzebne. Tryb Plan jest do tego stworzony.

Tryb Plan przeskanuje twoją bazę kodu i wyprodukuje ustrukturyzowany podział. Typowy wynik może wyglądać tak:

  • 95 prostych komponentów klasowych (bez stanu, bez lifecycle) — migracja automatyczna
  • 50 średnich komponentów (stan i componentDidMount) — półautomatyczne
  • 35 złożonych komponentów (wiele lifecycle methods, shouldComponentUpdate) — wymaga przeglądu
  • 45 komponentów podłączonych do Redux — zależy od migracji Zustand
  • 30 definicji tras — migracja wsadowa po komponentach

Ta inwentaryzacja staje się twoją mapą drogową migracji.

Najbezpieczniejsza strategia migracji to strangler fig: nowy kod używa nowych wzorców, stary kod jest migrowany przyrostowo, a oba współistnieją do ukończenia migracji. Reguły projektu Cursor egzekwują tę granicę.

.cursor/rules/migration.md
# Reguły migracji (aktywne)
## Nowy kod
- Wszystkie nowe komponenty MUSZĄ być komponentami funkcyjnymi z hookami
- Całe nowe zarządzanie stanem MUSI używać store'ów Zustand
- Wszystkie nowe trasy MUSZĄ używać wzorca data loader z React Router v7
- Nowy kod nie może używać: komponentów klasowych, Redux connect(), React Router v5 Switch
## Współistnienie
- Stare komponenty klasowe mogą importować nowe hooki przez funkcje wrapper
- Stare komponenty podłączone do Redux mogą czytać ze store'ów Zustand przez bridge
- Oba systemy routingu działają jednocześnie przez warstwę kompatybilności
## Status migracji
- Komponenty: 45/180 zmigrowanych (25%)
- Store'y Redux: 2/8 zmigrowanych (25%)
- Trasy: 0/30 zmigrowanych (0%)

Aktualizuj status migracji w tym pliku reguł w miarę postępów. Agent czyta go przy każdej interakcji, więc zawsze zna aktualny stan migracji.

Najłatwiejsza migracja: komponenty klasowe bez stanu i bez lifecycle methods.

Do migracji wsadowej możesz przetwarzać wiele plików naraz:

Migrate these 5 stateless class components to functional components.
Apply the same transformation to each:
@src/components/Badge.tsx
@src/components/Card.tsx
@src/components/Divider.tsx
@src/components/Icon.tsx
@src/components/Label.tsx
For each file: convert class to function, destructure props, preserve behavior exactly.
After migration, run "npm run type-check" to verify TypeScript compilation.

Komponenty ze stanem i lifecycle methods wymagają ostrożniejszej transformacji:

Złożone komponenty wymagają indywidualnej uwagi:

Migracja Redux do Zustand jest najwyższego ryzyka, ponieważ zarządzanie stanem dotyka każdego podłączonego komponentu. Migruj jeden store naraz.

Migrację routera najlepiej przeprowadzić wsadowo, ponieważ trasy są od siebie zależne:

Migracja Webpack do Vite jest zazwyczaj robiona w jednej sesji, ponieważ dotyczy tylko konfiguracji:

Agent migruje kod niepoprawnie, a testy przechodzą, ponieważ testy też są nieaktualne. To najgroźniejszy błąd migracji. Przed migracją komponentu zweryfikuj, że jego istniejące testy faktycznie testują zachowania, na których ci zależy. Poproś Agenta: “Przed migracją tego komponentu przejrzyj jego plik testowy. Czy testy pokrywają kluczowe zachowania, czy tylko sprawdzają, że się renderuje?”

Bridge migracyjny powoduje problemy z wydajnością. Synchronizacja stanu między Redux a Zustand przy każdej zmianie tworzy niepotrzebne re-rendery. Utrzymuj bridge prostym (synchronizacja jednokierunkowa) i usuń go, gdy tylko wszystkie konsumenci danego store’u będą zmigrowane.

Częściowo zmigrowany kod myli Agenta. Gdy twoja baza kodu ma zarówno stare, jak i nowe wzorce, Agent czasem generuje kod używając starego wzorca, ponieważ widzi więcej jego przykładów. Plik reguł migracji na początku tego artykułu temu zapobiega — ale tylko jeśli jest ustawiony na “Always Apply.”

Migracja zatrzymuje się na 80%. Ostatnie 20% komponentów jest zawsze najtrudniejsze, ponieważ to najbardziej złożone komponenty. Nie zostawiaj ich. Zaplanuj dedykowane sprinty migracyjne i użyj trybu Plan w Cursor, aby rozbić każdy złożony komponent na mniejsze, łatwiejsze do ogarnięcia kroki.

Potrzebny jest rollback po częściowej migracji. Zachowaj stare ścieżki kodu dostępne (zakomentowane lub za feature flagami) do czasu zweryfikowania migracji na produkcji. Checkpointy Cursor pomagają z rollbackami per sesja, ale dla wielodniowych migracji używaj gałęzi Git.