Traktowanie folderów lokalnych jako wyniku budowy za pomocą Expo Prebuild i CNG
Jak Continuous Native Generation umożliwia aplikacji Expo korzystanie z dostosowanych modułów natywnych, pluginów konfiguracyjnych oraz sekretów EAS bez konieczności zapisywania zmian lub ręcznego edytowania folderów iOS i Android.
Przez lata zespoły React Native w Expo musiały stawiać czoła temu samemu dylematowi: gdy projekt wymagał specjalnego modułu natywnego, audio w tle lub SDK od dostawcy, rozwiązaniem było expo eject, w wyniku czego schludny projekt JavaScript nagle posiadał pełne katalogi ios i android. Od tego momentu zespół musiał również zarządzać CocoaPods, edytować plik build.gradle oraz naprawiać błędy w Xcode. Continuous Native Generation (CNG) i Expo Prebuild eliminują ten kompromis. Ten przewodnik wyjaśnia, jak działa ten model, w jaki sposób plagiiny konfiguracyjne zastępują ręczną edycję kodu natywnego, jak odzyskać kontrolę nad uszkodzonymi lokalnymi budowaniami dla Androida oraz jak wprowadzać poufne dane do budowań w chmurze bez ich zapisywania.
Kod natywny jako artefakt budowania
CNG opiera się na jednej zasadzie: projekty natywne są czymś, co generuje się automatycznie, a nie czymś, co trzeba ręcznie utrzymywać.
Wykonanie polecenia npx expo prebuild tworzy foldery ios i android na podstawie jedynego źródła prawdy, czyli plików app.json lub app.config.js. Narzędzie to czyta tę konfigurację, stosuje opisane w niej zmiany typu native i generuje kompletnymi projektami gotowymi do skompilowania.
Ponieważ foldery te można odtworzyć w każdym momencie, wiele zespołów dodaje elementy /ios i /android do pliku .gitignore. Gdy zależność typu native znajdzie się w uszkodzonym stanie lub po aktualizacji React Native, foldery te są usuwane i ponownie generowane. Codzienne pytanie zmienia się z „Co ktoś zmienił w projekcie Xcode?” na „Co deklaruje konfiguracja?”.
To określa również jedną z zasad modelu: po utworzeniu folderów natywnych nie należy ich edytować ręcznie. Każda zmiana dokonana ręcznie znika podczas następnej procedury przygotowawczej. Jeśli potrzebujesz jakiejś zmiany, musi ona zostać uwzględniona w konfiguracji.
Wtyczki konfiguracyjne zastępują ręczną edycję plików natywnych
To rodzi oczywiste pytanie: jak dodać uprawnienia do pliku AndroidManifest.xml lub dostosować plik AppDelegate.mm, jeśli utworzone pliki są niedostępne do edycji?
Odpowiedzią są wtyczki konfiguracyjne. Wtyczka konfiguracyjna to funkcja w języku JavaScript, która jest wykonywana podczas procedury przygotowawczej i modyfikuje projekt natywny w kontrolowany, powtarzalny sposób. Aplikacje wymagające skomplikowanych funkcji natywnych, takie jak przetwarzanie mowy w czasie rzeczywistym lub renderowanie modeli 3D, polegają na bibliotekach wymagających głębokich integracji z systemem natywnym, a te biblioteki zazwyczaj dostarczają własne wtyczki.
Zamiast edytować kod źródłowy, wymienia się plugin oraz jego opcje w pliku app.json. Poniższy przykład wykorzystuje expo-build-properties, aby ustawić wartość compileSdkVersion dla Androida na 34 – wartość, która w przeciwnym razie znajdowałaby się w pliku Gradle:
{
"expo": {
"plugins": [
[
"expo-build-properties",
{
"android": {
"compileSdkVersion": 34
}
}
]
]
}
}
Podczas kolejnego kroku przedbudowy plugin zapisuje tę ustawienie w wygenerowanym projekcie Androida. Ponieważ zmiana jest deklarowana, a nie wprowadzana ręcznie, przetrwa każdą regenerację i będzie widoczna podczas przeglądu kodu.
Zachowanie sprawności lokalnych budów dla Androida
Expo Go jest doskonałe do wczesnego tworzenia prototypów, ale zawiera jedynie moduły natywne dołączone do niego. Gdy zaczynasz korzystać z niestandardowego kodu natywnego, testujesz aplikację przy użyciu wersji rozwojowych, wprowadzając polecenia npx expo run:android lub npx expo run:ios. Jest to szczególnie ważne dla aplikacji wykonywających intensywne obliczenia na urządzeniu, takich jak funkcje AI, gdzie konieczne jest sprawdzenie rzeczywistej wydajności na urządzeniu lub emulatorze.
Narzędzia do pracy z Androidem słyną z niestabilnych buforów pamięci. Typowy scenariusz: dodajesz zależność, a kolejna lokalna kompilacja zawodzi z niejasnym błędem w Javie lub Gradle. Przyczyną jest zazwyczaj przestarzały wynik kompilacji, a nie twój kod.
Najpierw spróbuj wykonać czystą kompilację. Wejdź do utworzonej katalogu android, uruchom zadanie clean w Gradle, aby usunąć zapisane wyniki, a następnie wróć do korzenia projektu i skompiluj ponownie:
cd android
./gradlew clean
cd ..
npx expo run:android
Jeśli samo wykonanie polecenia „clean” nie pomaga, CNG oferuje silniejszą opcję: npx expo prebuild --clean usuwa i całkowicie regeneruje foldery typu native, co jest bezpieczne właśnie dlatego, że nic w nich nie jest ręcznie utrzymywane. Włączenie obu tych praktyk do codziennej rutyny pozwala uniknąć długich sesji debugowania.
Dostarczanie haseł do budowy w chmurze EAS
CNG jest najskuteczniejszy, gdy łączy się z EAS (Expo Application Services) do budowy w chmurze.
Weźmy na przykład monitorowanie błędów. Aplikacje produkcyjne tego potrzebują, a integracja z Sentry wymaga przesyłania map źródłowych, co wymaga tokena SENTRY_AUTH_TOKEN. Tradycyjnie ten token musiał trafiać do każdego środowiska budowy, pozostając jednocześnie poza repozytorium, co utrudniało jego zarządzanie.
Z CNG i EAS dodajesz plugin konfiguracyjny Sentry do pliku app.json i nigdy nie zapisujesz tokena. Zamiast tego rejestrujesz go jako zmienną środowiskową w EAS za pomocą CLI, nadając mu dostęp typu secret i zakres projektu, dzięki czemu jest dostępny podczas budowania, ale nie jest wyświetlany później. Wykonaj komendę raz, zastępując wartość placeholdera swoim rzeczywistym tokenem:
eas env:create --name SENTRY_AUTH_TOKEN --value your_token_here --visibility secret --scope projecteas env:create --name SENTRY_AUTH_TOKEN --value your_token_here --visibility secret --scope project
Podczas budowania w chmurze EAS uruchamia proces prebuild w celu utworzenia projektów natywnych, plugin Sentry odczytuje tajemnicę z środowiska, konfiguruje natywny SDK i przesyła mapy źródłowe. Żaden plik natywny ani token nie trafia do systemu kontroli wersji. Dokładne flagi komendy eas env:create mogą ulegać zmianom pomiędzy wersjami CLI, dlatego jeśli komenda zostanie odrzucona, sprawdź aktualną dokumentację EAS.
Gdy CNG wymaga dodatkowej ostrożności
Model jest potężny, ale w niektórych sytuacjach konieczne jest dokładne planowanie:
- Biblioteki bez wtyczek. Jeśli natywne SDK nie posiada wtyczki konfiguracyjnej, być może będziesz musiał sam napisać małą lokalną wtyczkę zamiast edytować generowane pliki.
- Istniejące projekty typu brownfield. Aplikacje z latami ręcznie edytowanego kodu natywnego nie mogą po prostu usunąć swoich folderów; migracja oznacza najpierw przeniesienie każdej modyfikacji do pliku konfiguracyjnego.
- Dyscyplina zespołu. CNG działa tylko wtedy, gdy wszyscy traktują
iosiandroidjako elementy jednorazowe. Jedna szybka edycja w Xcode zostanie bez echa utracona podczas następnej regeneracji.
Podsumowanie
Expo Prebuild i CNG sprawiają, że złożone aplikacje React Native klasy produkcyjnej stają się znacznie łatwiejsze w obsłudze, poprzez uczynienie warstw natywnych elementami jednorazowymi:
- Zadeklaruj wymagania natywne w pliku
app.jsonlubapp.config.js, a narzędzie prebuild samo wygeneruje resztę.
prebuild --clean, gdy lokalne budowanie zawodzi w tajemniczy sposób.SENTRY_AUTH_TOKEN w zmiennych środowiskowych EAS, a nie w repozytorium.Gdy projekty natywne zostają sprowadzone do wyników budowania, uwaga zespołu wraca na kod React Native, płynne interfejsy oraz funkcjonalności produktu.
Literatura pokrewna
- Łączenie modułu Turbo w aplikacji od początku do końca za pomocą React Native Codegen — Zdefiniuj typową specyfikację, uruchom proces generowania kodu i zaimplementuj moduł Turbo na iOS oraz Android przy użyciu metod synchronicznych, Promise, callback i event-emitter.
- Trwała zmiana tematu w React Native z użyciem Contextu i Hooków — Stwórz narzędzie do zmiany tematu w React Native przy użyciu Context, useState i useEffect: nawigacja kart, wybieracz tematu, przechowywanie danych w AsyncStorage oraz mechanizm ochronny podczas uruchamiania aplikacji.