Strona główna / Artykuły

Planowanie aktualizacji na Expo SDK 58: iOS 27, React Native 0.88 oraz nowe narzędzia

Praktyczny przewodnik po wersji beta Expo SDK 58: jakie zmiany dotyczą iOS 27 i React Native 0.88, które funkcje są eksperymentalne oraz jak bezpiecznie przetestować aktualizację.

Wydawca: REACTAPP.TOP18 min czytania4162 słów

Źródła: Expo SDK 58 Beta: What React Native Developers Actually Need to Know

Expo SDK 58 nie jest definiowany przez jedną kluczową funkcję. Zamiast tego dostępna jest długa lista zmian: obsługa iOS 27, React Native 0.88, szybsze budowanie aplikacji na Androidzie, tańsze wywołania modułów natywnych, elementy interfejsu na ekranie głównym Androida, integracja z Siri poprzez App Intents, interfejs wiersza poleceń przeznaczony do programowania agentów, bardziej rozwinięty Expo Router oraz eksperymentalny transformator oparty na języku Rust dla Metro. Ten przewodnik uporządkowuje tę listę według praktycznego wpływu, abyś mógł dowiedzieć się, które zmiany dotkną twoją bazę kodu, które otrzymujesz bezpłatnie, które są nadal eksperymentalne oraz jak przeprowadzić aktualizację bez uszkodzenia aplikacji produkcyjnej.

Traktuj SDK 58 jako wersję beta, ponieważ taką właśnie jest

W momencie pisania SDK 58 znajduje się w fazie beta, a Expo spodziewa się, że ta faza potrwa około trzech do czterech tygodni. Sprawdź aktualny stan w dzienniku zmian Expo przed planowaniem czegokolwiek związанego z datą wydania.

Okres beta to idealny czas na testowanie: kodu aplikacji, bibliotek od third party, dostosowanych modułów natywnych, procesu budowania oraz wszelkiego ręcznie napisanego kodu natywnego. To nieodpowiedni moment na aktualizację SDK w aplikacji produkcyjnej tuż przed weekendem. Natomiast w przypadku projektów pobocznych i narzędzi wewnętrznych beta stanowi sposób o niskim ryzyku, umożliwiający zobaczenie tego, co nadchodzi, oraz wczesne wykrycie problemów, póki istnieje jeszcze czas na ich naprawę u dostawcy.

iOS 27 i cykl życia oparty na scenach

Znaczną część motywacji do stworzenia SDK 58 stanowi iOS 27. Aplikacje skompilowane z użyciem SDK iOS 27 wykorzystują model cyklu życia oparty na scenach opracowany przez Apple, a Expo przeprojektowało swoją infrastrukturę natywną wokół tego modelu.

Kilka informacji w tle może pomóc. W starszym modelu UIApplicationDelegate zarządzał całym aplikacją: jednym oknem, jedną parą funkcji powiadamiających o uruchomieniu i działaniu w tle. Model scen dzieli te obowiązki, więc każda instancja interfejsu użytkownika (scena) ma swój własny cykl życia, który jest obsługiwany przez delegata sceny. Zadania, które wcześniej znajdowały się w delegacie aplikacji, takie jak reagowanie na aktywację aplikacji lub obsługa przychodzących adresów URL, mogą zostać przeniesione do funkcji powiadamiających na poziomie sceny.

W typowym projekcie Expo ta zmiana powinna być niewidoczna. Ma to znaczenie, gdy zaimplementowano własne modyfikacje w części natywnej. Częstym przykładem jest dodatkowa konfiguracja w funkcji powiadamiającej o uruchomieniu delegata aplikacji, jak w poniższej metodzie w języku Swift (pokazanej tutaj bez podświetlania składni):

func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions:
  [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
  // Custom initialization
  return true
}

Jeśli plik AppDelegate.swift zawiera znaczną ilość niestandardowej logiki, część z niej może teraz dotyczyć obsługi sceny, a nie pojedynczego globalnego okna aplikacji. Expo zaleca zapoznanie się z wytycznymi dotyczącymi migracji cyklu życia sceny, jeśli modyfikuje się delegata aplikacji natywnej.

Które projekty wymagają dokładniejszej analizy

Bardzo wiele aplikacji Expo w ogóle nie uruchamia pliku AppDelegate.swift, więc dla nich migracja powinna przebiec bez problemów. Jednak większe aplikacje z biegiem lat gromadzą coraz więcej kodu natywnego, i właśnie tam leży ryzyko. Sprawdź uważnie, czy twój projekt iOS posiada konfigurację natywną dla którychkolwiek z następujących elementów:

  • inicjalizacja SDK analitycznego
  • obsługa deep linków i universal linków
  • SDK do autoryzacji
  • powiadomienia typu push
  • SDK do płatności natywnych

Każdy z tych elementów zazwyczaj łączy się z funkcjami powrotnymi przy uruchamianiu lub w adresach URL, które to właśnie funkcje są wpływane przez model scen. Należy wyraźnie przetestować te procesy, zamiast zakładać, że udane skompilowanie oznacza działającą aplikację.

React Native 0.88 i ścisła API TypeScript

Beta wersja SDK 58 jest dostępna wraz z kandydatem na wydanie React Native 0.88. Dlatego aktualizacja Expo oznacza konieczność przyjęcia wszystkich zmian wprowadzonych zarówno w React Native 0.87, jak i 0.88, a nie tylko w jednym z tych wydań.

Pierwszą zmianą, na którą najprawdopodobniej natrafisz, jest ścisła API TypeScript, która bardziej restrykcyjnie określa, co stanowi publiczną API React Native. Głównymi ofiarami są importy odnoszące się do plików wewnętrznych:

import Something from 'react-native/Libraries/...';

Aplikacje i biblioteki od lat używały takich głębokich importów, zazwyczaj dlatego, że publiczny punkt wejścia nie udostępniał tego, czego potrzebowały. Zawsze działało to przypadkowo: ścieżki plików wewnętrznych mogą się zmienić lub ulec modyfikacji w każdej wersji bez uprzedzenia. React Native teraz wyznacza wyraźną granicę pomiędzy modułami publicznymi a prywatnymi, więc kodbase pełen głębokich importów powinien potraktować wersję SDK 58 jako sygnał do ich uporządkowania. Jeśli jakaś biblioteka w twoim drzewie zależności tak robi, sprawdź, czy nowsza wersja już to naprawiła.

Usunięte API, takie jak InteractionManager

Część starszych API również zniknęła, a InteractionManager jest jednym z tych, które należy sprawdzić. Kod, który odkłada intensywne obliczenia do momentu zakończenia animacji i interakcji, często wygląda w ten sposób:

InteractionManager.runAfterInteractions(() => {
  loadHeavyContent();
});

Zalecaną alternatywą jest standardowe API callbacku idle:

requestIdleCallback(() => {
  loadHeavyContent();
});

Semantyka jest podobna, ale nie identyczna. InteractionManager czekał, aż zakończą się zarejestrowane interakcje, natomiast requestIdleCallback uruchamia funkcję zwrotną, gdy wątek JavaScript ma wolny czas. W większości przypadków typu „załaduj to po pojawieniu się ekranu” różnica ta jest nieistotna, ale jeśli polegasz na tym, aby odczekać konkretną animację, sprawdź zachowanie na rzeczywistym urządzeniu.

W małej aplikacji ta migracja zwykle przebiega szybko. W starszej aplikacji z wieloma zależnościami wykonaj aktualizację na dedykowanej gałęzi i pozwól kompilatorowi TypeScript wylistować wszystkie problemy, zanim zaczniesz coś zmieniać. Błędy kompilatora staną się twoją listą kontrolną migracji.

Szybsze budowanie czystych aplikacji Android

expo-modules-core dostarcza teraz uprzednio skompilowane biblioteki natywne dla Androida. Wcześniej czysta kompilacja aplikacji na Androidzie pochłaniała znaczną część czasu na kompilowanie kodu C++, od którego zależą moduły Expo. SDK 58 pomija większość tego kroku.

Zgodnie z własnymi pomiarami Expo, przy użyciu pustej aplikacji SDK 58 na urządzeniu Apple M3 Pro, czas potrzebny na czystą kompilację w trybie debugowania dla Androida zmniejszył się z około 80 sekund do około 39 sekund. Twoje wyniki będą się różnić w zależności od rozmiaru projektu i sprzętu, ale oszczędność wynika z całkowitego pominięcia tego kroku, więc powinna być widoczna we wszystkich projektach wykorzystujących moduły Expo.

Korzyści są wielokrotnie większe w środowisku CI. Zespół, który otwiera dwadzieścia żądań pull request dziennie, z których każde uruchamia budowanie aplikacji dla Androida, płaci za koszty kompilacji przy każdym uruchomieniu, a maszyny CI często startują z czystych buforów pamięci. Oszczędzenie pół minuty raz nie jest niczym wyjątkowym. Jednak oszczędzenie tego czasu przy każdym lokalnym budowaniu, każdej zadaniu w CI, każdej gałęzi funkcjonalnej oraz przy każdym budowaniu wersji skutkuje realnym oszczędzeniem czasu i zasobów obliczeniowych. Szybkość budowania to również forma wydajności, tylko mierzona w minutach pracy programistów, a nie w szybkości odświeżania klatek.

Taniejsze wywołania między JavaScript a kodem natywnym

Prace nad poprawą wydajności w SDK 58 nie ograniczają się tylko do procesu budowania aplikacji. Expo zmniejszyło również koszt wywoływania modułów natywnych, przy czym większe korzyści występują na iOS. Przenoszenie długich ciągów znaków odbywa się znacznie szybciej, a obietnice zwracane przez asynchroniczne funkcje natywne generują mniejszy obciążenie.

Nie musisz nic zmieniać, aby skorzystać z tych ulepszeń: istniejące moduły Expo automatycznie korzystają z nich po aktualizacji.

To ma szczególne znaczenie dla aplikacji, które często przechodzą między środowiskiem JavaScript a natywnym. Rozważmy taki przykład wywołania:

const result = await SomeNativeModule.processLargePayload(data);

Funkcja natywna może wykonywać swoje zadania szybko, ale za każde wywołanie nadal trzeba przekształcać argumenty na typy natywne i z powrotem na wartości JavaScript. Jeśli aplikacja wykona takie wywołania tysiące razy, na przykład podczas przetwarzania strumienia danych z czujników lub synchronizacji dużych obciążeń, niewielka oszczędność przy każdym takim przejściu daje zauważalną różnicę.

Expo Modules 2.0: klasy natywne zamiast DSL

Dla zespołów, które piszą własne moduły natywne, Expo Modules 2.0 to jedna z najważniejszych zmian. W chwili pisania jest w wersji beta zarówno na iOS, jak i Android.

Bieżąca API Expo Modules opisuje moduł za pomocą DSL: bloku definicji, w którym deklaruje się funkcje, właściwości i zdarzenia. Expo Modules 2.0 przyjmuje bardziej konwencjonalne podejście – pisze się zwykłą klasę w języku Swift lub Kotlin i adnotuje jej elementy, które mają być dostępne dla JavaScriptu.

Praktycznym efektem jest to, że kod natywny zachowuje się jak prawdziwy kod natywny. Swift wygląda jak Swift, a Kotlin jak Kotlin, bez konieczności najpierw opanowania specyficznej warstwy frameworku. To obniża bariery dla programistów, którzy znają platformę, ale nie Expo, a także pomaga narzędziom do kodowania opartym na AI, ponieważ w ich danych treningowych znajduje się znacznie więcej zwykłego kodu w języku Swift i Kotlin niż kodu w DSL Expo.

Istnieje również aspekt wydajności. Powiązania mogą być generowane w czasie budowania aplikacji zamiast być rozwiązywane dynamicznie w trakcie jej działania, a testy wydajnościowe Expo pokazują duże ulepszenia w kilku mikrotestach. Mikrotesty izolują pojedynczą operację, więc rzadko przekładają się jedno do jednego na szybsze działanie aplikacji; same w sobie nie stanowią powodu do przeprojektowania architektury natywnej. Jeśli chcesz głębszej informacji na temat tego, dlaczego statyczne powiązania są szybsze, porównanie w Nitro Modules: jak statyczne powiązania przewyższają React Native TurboModules omawia ten sam zasadę. Co wyróżnia Expo Modules 2.0, to fakt, że sprawia on, iż moduły są jednocześnie prostsze w pisaniu i szybsze, co jest rzadką kombinacją.

Widżety na ekranie głównym w Androidzie

expo-widgets obsługuje teraz Android, co otwiera możliwości tworzenia nowych funkcji w różnych aplikacjach: narzędziach do śledzenia nawyków, programach finansowych, aplikacjach dostawczych, aplikacjach fitness, menedżerach zadań oraz kalendarzach.

Aplikacja do śledzenia nawyków mogłaby pokazywać dzisiejszy postęp bez konieczności jej otwierania. Aplikacja finansowa mogłaby wyświetlać krótki podsumowanie budżetu z takim nagłówkiem:

Monthly Budget

oraz szczegółowy rozkład pozostałej kwoty według kategorii poniżej:

₹34,500 remainingFood        ₹8,200
Travel      ₹3,400
Shopping    ₹5,100

Menedżer zadań mógłby pokazywać trzy najważniejsze zadania dnia bezpośrednio na ekranie głównym.

W systemie Android każdy widget uruchamia swój własny plik JavaScript na dedykowanym silniku Hermes, obsługuje interakcje użytkownika i może korzystać z kolorów Material, dzięki czemu łączy się z tematem systemowym. Warto zrozumieć specyfikę tego oddzielnego silnika: widget nie dzieli pamięci ani stanu z działającą aplikacją, więc dane muszą być do niego przekazywane wyraźnie, zamiast być odczytywane z wewnętrznego magazynu aplikacji. Dla zespołów pracujących na kilku platformach obecność widgetów na obu platformach w ekosystemie Expo eliminuje kolejny powód do utrzymywania oddzielnych implementacji natywnych.

App Intents: Siri, Shortcuts i Spotlight

expo-app-intents łączy aplikacje Expo z systemem App Intents firmy Apple, który stanowi mechanizm za kilkoma interfejsami systemowymi:

  • Siri
  • Shortcuts
  • Spotlight
  • Apple Intelligence

Załóżmy menedżer zadań. Zwykle ukończenie zadania oznacza otwarcie aplikacji, znalezienie odpowiedniego elementu i jego kliknięcie. Gdy intencja jest dostępna, użytkownik może po prostu zapytać Siri:

"Ukończ przesyłanie dokumentów o identyfikatorze Upload ID."

Siri znajduje odpowiednie zadanie i uruchamia akcję zadeklarowaną przez Twoją aplikację. Twój kod JavaScript otrzymuje tę instrukcję i aktualizuje dane aplikacji. W przykładzie z Expo dzieje się to bez przenoszenia aplikacji na pierwszy plan.

Szerzej rzecz biorąc, to oznacza zmianę w sposobie strukturyzowania aplikacji mobilnych. Ikona aplikacji przestaje być jedynym punktem wejścia – niektóre akcje są uruchamiane przez Siri, inne przez widgety, jeszcze inne przez wyszukiwanie w Spotlight, a jeszcze inne przez automatyzacje Shortcuts użytkownika. Aplikacja staje się zbiorem funkcji, które system operacyjny może udostępnić tam, gdzie są przydatne, co warto wziąć pod uwagę podczas projektowania nowych funkcjonalności.

Jedna ważna uwaga: expo-app-intents znajduje się w wersji alfa w momencie pisania tego tekstu. Można z nim eksperymentować, ale nie należy jeszcze opierać na nim kluczowych procesów biznesowych.

Expo UI zbliża się do SwiftUI i Jetpack Compose

Expo UI nadal pogłębia integrację z SwiftUI i Jetpack Compose. SDK 58 dodaje elementy nawigacji typu SwiftUI dla iOS:

NavigationStack
NavigationLink
NavigationDestination
Toolbar

Są one powiązane z własnymi elementami nawigacji SwiftUI, dzięki czemu otrzymujemy natywną nawigację typu stack oraz paski narzędzi, zamiast ich rekonstrukcji w języku JavaScript. W tym wydaniu dodano również więcej komponentów Jetpack Compose oraz udoskonalono istniejące komponenty uniwersalne, które działają na różnych platformach.

Kolejna, mniejsza poprawka okazuje się zaskakująco przydatna: każdy komponent w dokumentacji Expo UI ma teraz dołączone przykłady wizualne. Bez zrzutów ekranu wybór komponentu interfejsu użytkownika często prowadzi przez frustrujący cykl:

  1. Znajdź komponent, który brzmi odpowiednio.
  2. Poznaj jego właściwości.
  3. Podłącz go do ekranu.
  4. Zapuść aplikację.
  5. Odkryj, że nie wygląda wcale tak, jak sobie wyobrażałeś.
  6. Rozpocznij od nowa z innym komponentem.

Widok renderowanego komponentu obok jego API przerywa ten błędny cykl.

Device Hub i sterowanie symulatorem w przeglądarce

Xcode 27 zastępuje Simulator.app przez Device Hub, a Expo CLI rozumie nowy proces pracy. Expo eksperymentuje również z oddzielnym pakietem, expo-device-hub, który dostarcza lokalną panel kontrolny w przeglądarce dla twoich symulatorów i emulatorów.

Z tego panelu możesz przeglądać:

  • żywy obraz ekranu urządzenia
  • zużycie CPU i pamięci
  • ruch sieciowy
  • opcje wyglądu, takie jak tryb jasny i ciemny
  • opcje dostępności

Możesz również dotykać, przesuwać palcem i pisać na urządzeniu bezpośrednio z przeglądarki. Aby to wypróbować, zainstaluj pakiet i uruchom serwer deweloperski:

npx expo install expo-device-hub
npx expo start

Jeśli twoja praca polega na ciągłym przemieszczaniu się pomiędzy edytorem, terminalami, emulatorem Androida, symulatorem iOS oraz osobnymi narzędziami do analizy wydajności, połączenie niektórych z tych funkcji w jednej karcie przeglądarki może znacznie ułatwić pracę dewelopera.

Expo pracuje również nad EAS Simulator, który ma zapewnić podobne doświadczenie za pomocą symulatorów hostowanych w chmurze, dzięki czemu nie będzie konieczne instalowanie Xcode lub Android Studio lokalnie.

CLI stworzona dla agentów programistycznych

To rozszerzenie jasno pokazuje, w jakim kierunku zmierzają narzędzia dla deweloperów. Expo opublikowało eksperymentalny pakiet:

@expo/agent-cli

Agenty kodujące mają trudności, gdy muszą zdecydować, który z kilku narzędzi użyć: Expo CLI, EAS CLI, expo-doctor itp., z których każde ma własne flagi i format wyjściowy. CLI agenta obejmuje je jedną spójną interfejsem. Konfiguracja tego rozwiązania dla projektu wygląda następująco:

npx @expo/agent-cli@latest agents:setup

Kilka z jego poleceń ilustruje tę koncepcję. Pierwsze z nich jest:

status

Sprawdza na przykład kompatybilność z Expo Go bez uruchamiania aplikacji. Następne polecenie to:

dev

Uruchamia środowisko rozwojowe i próbuje znaleźć najszybszą drogę do działającej aplikacji. Ostatnie polecenie to:

smoke

Uruchamia aplikację, robi jej zrzut ekranu, a następnie ponownie ją wyłącza.

Ostatni z tych polecenia jest najciekawszy dla zautomatyzowanych procesów pracy. Załóżmy, że poprosisz agenta o dodanie ekranu ustawień i sprawdzenie, czy aplikacja nadal się uruchamia. Zamiast zakładać automatycznie, że edycja zadziałała poprawnie, agent może wykonać test sprawdzający i przyjrzeć się wynikowi. To niewielki krok od agentów jako generatorów kodu w stronę agentów, które potrafią weryfikować własną pracę – właśnie w tym leży ich główna praktyczna wartość. Pakiet jest eksperymentalny, więc oczekuj zmian w jego poleceniach.

Expo Router usprawnia kilka funkcji

W SDK 58 nastąpiła znacząca aktualizacja Expo Routera. Kilka funkcji, które wcześniej były eksperymentalne, jest teraz stabilnych:

  • loaderzy danych, służące do pobierania informacji o trasie przed renderowaniem ekranu
  • rendering po stronie serwera dla wyjścia internetowego
  • middleware działający przed dotarciem żądania do konkretnej trasy
  • taby natywne wspierane przez paski tabów platformy
  • paski narzędziowe

Wewnątrz aplikacji nawigacja została również przepisana, dzięki czemu jej stan jest bardziej deterministyczny – to oznacza, że ta sama sekwencja działań zawsze prowadzi do tego samego stanu. Większość aplikacji nie powinna zauważyć żadnej różnicy. Jeśli stworzyłeś własne narzędzia nawigacyjne lub importujesz treści bezpośrednio z podanego ścieżki, przeczytaj uważnie przewodnik migracyjny:

expo-router/react-navigation

W sieci routy asynchroniczne są teraz standardem. Każda trasa może zostać podzielona na osobny plik JavaScript i załadowana w momencie, gdy użytkownik do niej przejdzie, zamiast wysyłać kod wszystkich ekranów przy pierwszym załadowaniu strony. Dla aplikacji webowych zbudowanych przy użyciu Expo Router jest to rozsądny standard, ponieważ czas początkowego załadowania jest zazwyczaj tym, co najbardziej rzuca się w oczy użytkownikom. Pamiętaj, że oznacza to również, iż trasa może zostać na chwilę załadowana podczas pierwszej wizyty, dlatego stan załadunku w aplikacjach internetowych wymaga szybkiego przeanalizowania.

Eksperymentalny transformator w języku Rust dla Metro

Technicznie rzecz biorąc, może to być najciekawsza zmiana w tym wydaniu, chociaż jest ona wyraźnie eksperymentalna. Expo testuje transformator JavaScript napisany w Rust o nazwie Noxcturnal, stworzony na bazie zestawu narzędzi oxc.

Znaczna część czasu potrzebnego na tworzenie „zimnych” pakietów w Metro jest poświęcana transformacjom realizowanym przez Babel: analizie każdego pliku, stosowaniu pluginów i generowaniu wyników. Zastąpienie tego kroku kodem natively napisanym w Rust pozwala bezpośrednio uderzyć w najdroższy element procesu. W testach Expo transformacje poszczególnych modułów były około trzy razy szybsze, a całe „zimne” pakiety około dwa razy szybsze. Jeden duży aplikacyjny test składający się z około 5 500 plików przyspieszył się z 5,26 sekundy do 2,46 sekundy.

Możesz to włączyć za pomocą flagi eksperymentalnej w swojej konfiguracji:

experiments: {
  noxcturnalTransformWorker: true
}

Znajdź granice przed włączeniem tej funkcji. Projekty, które polegają na niestandardowych wtyczkach Babel, ustawieniach wstępnych lub specjalistycznych transformacjach, mogą nadal korzystać z Babel, więc przyspieszenie zależy od tego, jak standardowa jest Twoja konfiguracja. Ponieważ ta funkcja jest eksperymentalna, jej zachowanie i konfiguracja mogą ulegać zmianom pomiędzy wersjami.

To rozwiązanie jest zgodne z trendem panującym w szerszym ekosystemie, gdzie narzędzia do JavaScriptu o kluczowym znaczeniu dla wydajności od kilku lat przechodzą z JavaScriptu na Rust. Expo bada teraz tę samą drogę dla Metro.

Mniej niepotrzebnych ponownych budów w języku natywnym

Domyślne zachowanie dotyczące tworzenia „odcisku palca” w SDK 58 to teraz ustawienie balanced. Odcisk palca to hasz wszystkich elementów wpływających na budowę w języku natywnym; gdy ulega zmianie, narzędzia Expo zakładają, że potrzebna jest nowa binarna wersja w języku natywnym.

To brzmi nudno, dopóki nie oszczędza to konieczności ponownego budowania aplikacji w wersji natywnej po edycji, która w ogóle nie wpływała na kod natywny. W zależności od ustawień, zmiana czegoś takiego jak wersja aplikacji w pliku app.json kiedyś powodowała zmianę „odcisku palca” aplikacji. Ustawienie zrównoważone stara się ignorować zmiany, które nie wpływają istotnie na działanie aplikacji w wersji natywnej. Codzienny efekt jest prosty: mniej niepotrzebnych ponownych budowań, co oznacza również mniej zbędnych wersji binarnych, gdy polegasz na „odciskach palca”, aby zdecydować się pomiędzy aktualizacją bezpośrednią a nową wersją z sklepu. Nikt nie demonstruje takiej funkcji, ale wszyscy od niej korzystają.

Mniejsze ulepszenia, o których warto wiedzieć

Poza głównymi punktami, kilka aktualizacji modułów może być istotnych w zależności od twojej aplikacji:

  • expo-camera umożliwia skanowanie dokumentów wielostronicowych, co jest przydatne w skanerach paragonów, procesach przesyłania dokumentów, weryfikacji tożsamości (KYC) oraz zarządzaniu wydatkami.
  • expo-font obsługuje czcionki zmiennych rozmiarów na Androidzie, iOS i w przeglądarce.
  • expo-audio dostarcza funkcje sterowania ekranem blokującym z uwzględnieniem listy odtwarzania oraz możliwość nagrywania w formatach WAV/PCM.
  • expo-file-system dodaje więcej interfejsów API do generowania hashów oraz obsługę przeglądania plików w formie natywnej.
  • expo-notifications wprowadza nowe funkcje, takie jak dostarczanie powiadomień w formie budzika na Androidzie.
  • Integracja z PostHog umożliwia dołączanie informacji o wersji budowy EAS oraz aktualizacjach do zdarzeń analitycznych.

Żaden z tych elementów sam w sobie nie określa wersji produktu. Razem pokazują, jak szeroki stał się zakres obsługi tej platformy.

Zmiany istotne, które należy przejrzeć przed aktualizacją

Aktualizacje są ekscytujące aż do chwili, gdy budowa aplikacji zostaje przerwana, więc nie pomijaj tej części. Zanim przeniesiesz prawdziwy projekt do SDK 58, sprawdź poniższe kwestie.

Głębokie importy w React Native

Znajdź w bazie kodu ten prefiks ścieżki:

react-native/Libraries/

Każdy taki wynik to import wewnętrznych plików React Native, który może zostać odrzucony przez Strict TypeScript API. Sprawdź również katalog node_modules, a przynajmniej przejrzyj nieudane zależności, ponieważ biblioteki są częstym źródłem takich problemów.

Usunięte API w React Native

Pewnij się, że ani twoja aplikacja, ani jej zależności nadal nie używają API usuniętych w wersjach React Native 0.87 i 0.88, takich jak InteractionManager.

Własny kod AppDelegate

Jeśli projekt dla iOS zawiera modyfikacje związane z cyklem życia aplikacji, przejrzyj je pod kątem wymagań dotyczących cyklu życia opartego na scenach w iOS 27.

Własna nawigacja w Expo Router

Customowe narzędzia nawigacyjne oraz importy z expo-router/react-navigation są dotknięte zmianami w interfejsie wewnętrznym; postępuj zgodnie z przewodnikiem migracji.

Zapisy w systemie plików

File.write() jest teraz asynchroniczny. Kod, który zakłada istnienie pliku w następnej linii, nie będzie działać prawidłowo, chyba że poczeka na zakończenie tej operacji. Jeśli naprawdę potrzebujesz zachowania synchronicznego, przejdź na:

File.writeSync()

Wersja Node.js

Wersje Node.js obsługiwane przez Expo uległy aktualizacji. Sprawdź swoje lokalne środowisko oraz obrazy CI, zanim założysz, że nieudana kompilacja jest błędem Expo.

Bezpieczny sposób testowania aktualizacji

Nie zaczynaj od głównej gałęzi produkcyjnej. Stwórz dedykowaną gałąź migracyjną i przeprowadź tam aktualizację:

npx expo install expo@next --fix

Tag expo@next instaluje wersję beta, a opcja --fix dostosowuje pozostałe pakiety Expo do wersji kompatybilnych z nią.

Najpierw sprawdź te mniej istotne przepływy, ponieważ to one zwracają uwagę użytkowników, gdy coś się psuje:

  • Czy aplikacja w ogóle uruchamia się?
  • Czy logowanie i uwierzytelnianie działają poprawnie?
  • Czy użytkownicy mogą przemieszczać się między głównymi ekranami?
  • Czy łącza typu deep link otwierają właściwe miejsce?
  • Czy przychodzą powiadomienia typu push?
  • Czy użytkownicy mogą przesyłać zdjęcia i pliki?
  • Czy transakcje płatnicze są realizowane pomyślnie?
  • Czy budowa wersji dla Androida działa bez problemów?
  • Czy budowa wersji dla iOS działa bez problemów?

Dopiero gdy te testy przejdą pomyślnie, warto zająć się nowymi funkcjami. Nowe API są przyjemne w testowaniu; testy regresji natomiast zapewniają zadowolenie użytkowników.

Kierunek rozwoju Expo

Biorąc pod uwagę całość SDK 58, kierunek rozwoju jest ważniejszy niż jakakolwiek pojedyncza funkcja. Expo zaczęło się jako sposób na ułatwienie korzystania z React Native, a stopniowo staje się kompletną platformą aplikacji:

  • Expo Router do struktury aplikacji i nawigacji
  • Expo Modules dla natywnych API
  • EAS Build do kompilacji aplikacji
  • EAS Update do wdrażania aktualizacji
  • EAS Observe do monitorowania w środowisku produkcyjnym
  • Expo UI dla komponentów interfejsu natywnego
  • widgety i App Intents do integracji z systemem operacyjnym
  • narzędzia agenta do rozwoju wspomaganego przez AI

Oprócz tego Expo nadal inwestuje w infrastrukturę, której korzystają deweloperzy na co dzień: szybszą kompilację, tańsze połączenia z bibliotekami natywnymi, mniej konieczności ponownej kompilacji, lepsze tunelowanie, doskonalsze narzędzia do symulacji oraz ewentualnie szybsze pakowanie aplikacji. Nic z tego nie tworzy imponujących screenshotów, ale ułatwia codzienną pracę. Aby uzyskać szerszy obraz tego, jak to wpływa na pozycję Expo, zapoznaj się z dlaczego odejście Shopify od React Native nie zagraża Expo.

Czy powinieneś teraz dokonać aktualizacji?

W przypadku aplikacji produkcyjnej przetestuj ją przed zatwierdzeniem zmian. SDK 58 nadal jest w wersji beta, React Native 0.88 dostępny jest jako kandydat na wersję finalną, kilka nowych interfejsów API jest eksperymentalnych lub w wersji alpha, a przed wydaniem stabilnej wersji spodziewane są dodatkowe poprawki.

W przypadku projektu pobocznego, narzędzia wewnętrznego lub gałęzi przejściowej warto poświęcić czas na jej przetestowanie, szczególnie jeśli potrzebujesz obsługi iOS 27 lub chcesz wyprzedzić zmiany w React Native. Problemy znalezione podczas testów beta można nadal zgłosić i naprawić przed wydaniem stabilnej wersji, co jest o wiele łatwiejsze niż znajdowanie ich po tym, jak wszyscy inni już dokonali aktualizacji.

Jedynym poleceniem, które należy zapamiętać, jest to samo, od którego zaczynasz:

npx expo install expo@next --fix

Zrób to na gałęzi, a nie w środowisku produkcyjnym.

Główne wnioski

  • Zmiany, które najprawdopodobniej spowodują problemy podczas aktualizacji, to głębokie importy, usunięte API takie jak InteractionManager, niestandardowy kod AppDelegate oraz niestandardowi nawigatorzy Expo Router.
  • Szybsze budowanie aplikacji na Androidzie, tańsze wywołania w języku natywnym oraz mniej ponownych kompilacji wywołanych na podstawie danych o urządzeniu to korzyści dostępne bezpłatnie wraz z aktualizacją.
  • Expo Modules 2.0, agent CLI, Device Hub oraz Noxcturnal transformer są w fazie eksperymentalnej lub beta; warto je przetestować, ale jeszcze nie należy na nich polegać.
  • expo-app-intents znajduje się w wersji alpha, natomiast elementy typu widget na Androidzie umożliwiają wykorzystanie funkcji ekranu głównego przez zespoły pracujące na różnych platformach.
  • Proceduj z aktualizacją na dedykowanej gałęzi, najpierw przetestuj kluczowe ścieżki działania użytkownika, a nowe funkcje sprawdzaj dopiero po ich pomyślnym przetestowaniu.

Pozycje pokrewne

  • PWA, Swift i Kotlin, albo Expo: Wybór architektury aplikacji mobilnej — Porównaj PWA, w pełni natywne aplikacje napisane w Swift i Kotlin oraz Expo pod kątem bazy kodu, obecności w sklepach z aplikacjami, wydajności, dostępu do sprzętu, szybkości wypuszczania aktualizacji i kosztów, a następnie dokonaj wyboru.
  • Od jednego projektu do wielu ekranów: Lepszy proces tworzenia zasobów ekranu startowego — Dlaczego ekrany startowe zajmują więcej czasu, niż na to zasługuje ich projekt, jak stworzyć taki, który będzie funkcjonalny we wszystkich proporcjach ekranów, oraz co powinien robić skoncentrowany generator oparty na przeglądarce.
  • Biometryczna autentyfikacja poziomowa na iOS i Android z kluczami przytwierdzonymi do hardwaru — Dowiedz się, dlaczego sam Face ID nie dostarcza żadnych dowodów dla twojego serwera, oraz jak wykorzystać Secure Enclave i klucze Android Keystore do podpisywania jednorazowych wyzwań serwerowych.
  • Kierowanie dotykami powiadomień przez deep links w React Native — Ustaw universal links i app links, połącz Pusher Beams z aplikacją React Native oraz mapuj adresy URL internetowe na karty natywne, aby kliknięcie w powiadomienie otwierało właściwe miejsce.
  • Dlaczego Codegen zmusza do najpierw specyfikacji dla React Native TurboModules — Dowiedz się, jak React Native Codegen przekształca specyfikację TurboModule w TypeScript na umowę z czasem budowania, co się psuje, gdy jej pominiesz, oraz gdzie ta zasada przestaje obowiązywać.
  • Przechowywanie zmian themu w React Native z użyciem Context i Hooks — Stwórz mechanizm zmiany themu w React Native przy użyciu Context, useState i useEffect: nawigacja kart, wybieracz themu, przechowywanie danych w AsyncStorage oraz mechanizm ochronny podczas uruchamiania aplikacji.
  • Wiązanie modułu Turbo w aplikacji end to end z użyciem React Native Codegen — Zdefiniuj typowaną specyfikację, uruchom proces codegen i zaimplementuj moduł Turbo na iOS oraz Android przy użyciu metod synchronicznych, Promise, callback i event-emitter.