Codegen to narzędzie automatycznego generowania kodu w ekosystemie React Native, które tworzy obwiednie TypeScript, C++ i Objective-C na podstawie deklaratywnych specyfikacji interfejsów modułów natywnych. Deweloper opisuje tylko sygnatury metod i typy parametrów w pliku JavaScript, a Codegen generuje cały kod łączący między JS a stroną natywną. Według React Native Documentation (2025), Codegen skraca czas tworzenia modułu natywnego średnio o 60% dzięki automatyzacji rutynowego kodu.
Najważniejsze
Codegen (skrót od Code Generator) — to narzędzie wiersza poleceń wchodzące w skład React Native, które automatycznie generuje kod łączący do komunikacji między JavaScript a platformami natywnymi (iOS, Android). Codegen jest nieodłączną częścią nowej architektury React Native i jest używany zarówno dla Fabric (renderer), jak i TurboModules (moduły natywne).
Główna idea Codegen polega na podziale odpowiedzialności: deweloper opisuje „co” funkcja ma robić (jej sygnaturę), a Codegen generuje „jak” zostanie to przekazane na stronę natywną. Eliminuje to konieczność ręcznego pisania obwiedni C++ dla JSI, stubów Objective-C dla iOS i klas Java dla Android. Pojedyncze źródło prawdy — specyfikacja TypeScript — gwarantuje, że typy na wszystkich poziomach są zgodne, co eliminuje całą klasę błędów związanych z niezgodnością typów między JS a kodem natywnym.
Codegen został przedstawiony wraz z pierwszą stabilną wersją nowej architektury React Native (0.70+) i od tego czasu stał się obowiązkowym narzędziem do tworzenia modułów natywnych. Bez Codegen deweloper musiałby ręcznie pisać JSI Host Objects, co wymaga głębokiej znajomości C++ i zrozumienia wewnętrznego działania silników JavaScript.
Przed pojawieniem się Codegen tworzenie modułu natywnego dla React Native obejmowało trzy kroki: napisanie interfejsu JavaScript, implementacja modułu natywnego w Java/Objective-C i ręczne napisanie mostu. Przy zmianie sygnatury metody trzeba było synchronicznie aktualizować wszystkie trzy pliki. Codegen automatyzuje tę rutynę: zmiany wprowadza się tylko w specyfikacji TypeScript, a cała reszta jest generowana od nowa.
Codegen integruje się z procesem budowania React Native przez Metro i CocoaPods. Przy uruchomieniu budowania Codegen analizuje specyfikacje TypeScript, generuje pliki C++ i platformowe oraz umieszcza je w katalogu build. Oznacza to, że wygenerowany kod zawsze odpowiada bieżącym specyfikacjom i nie wymaga ręcznej aktualizacji.
Proces działania Codegen składa się z trzech etapów: parsowanie specyfikacji, budowanie pośredniej reprezentacji i generowanie plików docelowych. Każdy etap jest izolowany, co pozwala łatwo dodawać obsługę nowych platform lub języków generacji.
W pierwszym etapie Codegen odczytuje pliki specyfikacji w formacie TypeScript lub Flow. Specyfikacja opisuje interfejs modułu natywnego: nazwy metod, typy parametrów i wartości zwracanych. Codegen obsługuje typy prymitywne (number, string, boolean), a także złożone — obiekty, tablice, Promise i Callback. Specyfikacje są przechowywane w plikach z rozszerzeniem .ts lub .js w specjalnym katalogu projektu.
W drugim etapie Codegen buduje abstrakcyjne drzewo składniowe (AST) z odczytanych specyfikacji. AST reprezentuje strukturę danych w neutralnym formacie, niezwiązanym z konkretnym językiem generacji. Pozwala to generować kod C++ dla Fabric, Objective-C dla iOS i Java dla Android z jednego AST — nie jest wymagana żadna dodatkowa praca do obsługi wszystkich platform.
W trzecim etapie Codegen używa silnika szablonów (opartego na Mustache) do generowania plików docelowych platform. Każdy szablon odpowiada za konkretny typ pliku: plik nagłówkowy C++ (.h), implementację (.cpp), protokół Objective-C (.h) lub implementację (.mm), klasę Java. Szablony są dostarczane wraz z React Native, ale mogą być dostosowane do specyficznych potrzeb projektu.
// NativeCalculator.ts — specyfikacja modułu natywnego
import { TurboModule, TurboModuleRegistry } from 'react-native'
import { Double } from 'react-native/Libraries/Types/CodegenTypes'
export interface NativeCalculatorSpec extends TurboModule {
add(a: Double, b: Double): Double
multiply(a: Double, b: Double): Double
}
export default TurboModuleRegistry.<NativeCalculatorSpec>('NativeCalculator')
W tym przykładzie specyfikacja opisuje moduł NativeCalculator z dwiema metodami: add i multiply. Obie przyjmują Double i zwracają Double. Ciąg 'NativeCalculator' w TurboModuleRegistry wskazuje nazwę modułu, która będzie używana po stronie natywnej. Codegen na podstawie tej specyfikacji wygeneruje wszystkie niezbędne pliki dla Fabric i TurboModules.
W kontekście Fabric (nowy renderer React Native) Codegen odgrywa szczególną rolę. Fabric wymaga, aby każdy natywny komponent UI miał reprezentację C++, która może być utworzona i zarządzana przez JSI. Codegen generuje te reprezentacje C++ automatycznie na podstawie specyfikacji komponentów.
Dla komponentów UI Codegen generuje nie tylko klasę C++ Shadow Node, ale także reprezentacje platformowe. Na przykład dla niestandardowego komponentu Button na iOS Codegen utworzy klasę Objective-C, która rejestruje komponent w Fabric i łączy go z C++ Shadow Node. Deweloper musi tylko opisać właściwości komponentu (kolor, rozmiar, obsługę zdarzeń) w specyfikacji TypeScript.
Codegen obsługuje bezpośrednie i zwrotne przekazywanie danych. Direct Event (np. onPress) są generowane jako struktury C++ z polami, które są automatycznie serializowane przy przekazywaniu do JS. EventEmitter pozwala stronie natywnej wysyłać zdarzenia do JS bez żądania ze strony JS. Codegen generuje typowane otoczki dla obu kierunków, eliminując błędy niezgodności nazw pól.
| Komponent | Specyfikacja (TypeScript) | Generacja C++ | Generacja platformy |
|---|---|---|---|
| Metoda | add(a: Double): Double | JSI Host Function | NativeMethod na iOS/Android |
| Właściwość | color: String | Shadow Node prop | UIView/View właściwość |
| Zdarzenie | onPress: () => Void | Event struct | UIControl/View callback |
| Stała | PI: Double | Const getter | Constants export |
Twórcy bibliotek mogą dostarczać specyfikacje Codegen wraz z pakietem npm. Podczas instalacji biblioteki Codegen automatycznie wykrywa specyfikacje i generuje kod łączący dla bieżącej platformy. Jest to szczególnie ważne dla bibliotek natywnych, ponieważ użytkownik biblioteki nie musi znać C++, Objective-C ani Java — wystarczy zaimportować typy TypeScript i używać gotowych komponentów.
Codegen generuje pliki dla trzech środowisk docelowych: C++ (JSI), Objective-C (iOS) i Java (Android). Każdy plik ma ściśle określoną rolę i strukturę. Zrozumienie, jakie pliki są tworzone, pomaga w debugowaniu i w razie potrzeby ręcznej korekty wygenerowanego kodu.
Dla każdego modułu natywnego Codegen tworzy dwa pliki C++: nagłówkowy (.h) z deklaracją klasy Host Object i plik implementacji (.cpp) z metodami, które wywołują odpowiednie funkcje na platformie. Plik nagłówkowy zawiera klasę dziedziczącą po jsi::HostObject z nadpisaną metodą get do dostępu do funkcji modułu. Plik implementacji zawiera funkcje lambda, które przy wywołaniu z JS delegują wykonanie do modułu natywnego.
Dla iOS Codegen generuje protokół Objective-C i kategorię. Protokół deklaruje metody, które muszą być zaimplementowane przez moduł natywny. Kategoria na RCTCxxBridge zawiera kod łączący, który rejestruje moduł w RCTTurboModuleManager. Pozwala to wywoływać metody modułu Objective-C z C++ JSI przez standardowy mechanizm RCTBridge.
Dla Android Codegen generuje interfejs Java i klasę abstrakcyjną. Interfejs zawiera deklaracje metod modułu z poprawnymi typami Java. Klasa abstrakcyjna implementuje interfejs TurboModule i zawiera podstawową logikę rejestracji modułu w ReactPackage. Deweloper dziedziczy po tej klasie i implementuje tylko logikę biznesową metod.
// Struktura katalogów po uruchomieniu Codegen
build/
generated/
ios/
NativeCalculatorSpec.h // Protokół Objective-C
NativeCalculatorSpec.mm // Implementacja JSI
android/
NativeCalculatorSpec.java // Interfejs Java
NativeCalculatorModuleBase.java // Klasa bazowa
cxx/
NativeCalculator.h // Nagłówek C++ Host Object
NativeCalculator.cpp // Implementacja JSI C++
Cała ta struktura jest tworzona automatycznie podczas budowania projektu. Deweloper nie powinien edytować wygenerowanych plików — przy następnym budowaniu zostaną nadpisane. Jeśli trzeba zmienić zachowanie modułu, zmiany wprowadza się tylko w kodzie źródłowym implementacji natywnej (Java/Objective-C) lub w specyfikacji TypeScript.
Rozważmy pełny cykl pracy z Codegen na przykładzie tworzenia modułu natywnego do przechowywania danych w Keychain. To typowe zadanie wymagające dostępu do natywnego API iOS i Android.
Deweloper tworzy plik specyfikacji opisujący interfejs modułu KeychainStorage. Metody save i read przyjmują ciąg znaków i zwracają Promise, ponieważ praca z Keychain może być asynchroniczna na niektórych platformach.
import { TurboModule, TurboModuleRegistry } from 'react-native'
export interface KeychainStorageSpec extends TurboModule {
save(key: string, value: string): Promise<void>
read(key: string): Promise<string | null>
delete(key: string): Promise<boolean>
}
export default TurboModuleRegistry.<KeychainStorageSpec>('KeychainStorage')
Codegen uruchamia się automatycznie podczas budowania projektu React Native. Jeśli trzeba uruchomić go ręcznie, używa się polecenia npx react-native codegen. Codegen parsuje specyfikację i tworzy wszystkie niezbędne pliki w build/generated/. Deweloper widzi wynik w postaci wygenerowanych plików C++, Objective-C i Java, ale nie powinien ich edytować.
# Uruchom Codegen ręcznie
npx react-native codegen --target-path ./build/generated
# Po wygenerowaniu — zbuduj projekt
npx react-native run-ios
npx react-native run-android
Po wygenerowaniu i budowaniu deweloper importuje moduł jak zwykły typ TypeScript. IDE automatycznie podpowiada sygnatury metod dzięki wygenerowanym plikom .d.ts. TypeScript gwarantuje, że typy parametrów i wartości zwracanych są zgodne z implementacją natywną — jeśli w specyfikacji wskazano string, strona natywna otrzyma właśnie ciąg znaków.
import KeychainStorage from './NativeKeychainStorage'
async function storeToken(token: string) {
await KeychainStorage.save('auth_token', token)
}
async function getToken(): Promise<string | null> {
return KeychainStorage.read('auth_token')
}
W tym przykładzie widać, że kod JS nie zawiera żadnych wskazań platformy — jest taki sam dla iOS i Android. Cała specyfika platformy jest ukryta wewnątrz kodu wygenerowanego przez Codegen. Codegen przejmuje całą rutynową pracę tworzenia mostów, pozostawiając deweloperowi tylko logikę biznesową i sprawdzanie typów przez TypeScript.
Często zadawane pytania
Zazwyczaj nie — Codegen uruchamia się automatycznie podczas budowania projektu React Native przez Metro i CocoaPods. Do ręcznego uruchomienia używa się polecenia npx react-native codegen, co jest przydatne przy debugowaniu lub w pipeline'ach CI/CD do wstępnej generacji.
Tak, Codegen obsługuje typy prymitywne (number, string, boolean), obiekty z typowanymi polami, tablice, Promise i Callback. Niestandardowe typy definiuje się przez TypeScript interface — Codegen wygeneruje odpowiednie struktury C++ i klasy Java.
Przy następnym budowaniu Codegen regeneruje wszystkie pliki od nowa. Wygenerowane pliki nie powinny być edytowane ręcznie — są przeznaczone tylko do odczytu. Zmiany wprowadza się wyłącznie w specyfikacji TypeScript i natywnej implementacji modułu.
Technicznie tak, ale to nie ma sensu. Codegen został zaprojektowany specjalnie do generowania obwiedni kompatybilnych z JSI, które działają tylko z nową architekturą (Fabric i TurboModules). Dla starej architektury Bridge generacja nie jest wymagana — Codegen jest narzędziem wyłącznie nowej architektury.
Codegen obsługuje dwa formaty specyfikacji: TypeScript (preferowany) i Flow. TypeScript jest zalecany, ponieważ ma szersze wsparcie narzędzi i lepiej integruje się z IDE. Flow jest obsługiwany dla zachowania wstecznej kompatybilności z istniejącymi projektami Facebook.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również