React Native 0.79 - Szybsze narzędzia i wiele więcej
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →
Z przyjemnością ogłaszamy wydanie React Native 0.79!
Ta wersja wprowadza poprawy wydajności na wielu frontach oraz liczne poprawki błędów. Po pierwsze, Metro uruchamia się szybciej dzięki odroczonemu haszowaniu i zapewnia stabilne wsparcie dla eksportów pakietów. Czas uruchamiania na Androidzie również ulegnie poprawie dzięki zmianom w kompresji pakietów JS i wielu innym ulepszeniom.
Najważniejsze zmiany
Najważniejsze zmiany
Metro: Szybsze uruchamianie i wsparcie dla eksportów pakietów
Ta wersja zawiera Metro 0.82. Wersja ta wykorzystuje odroczone haszowanie, aby przyspieszyć pierwsze uruchomienie yarn start zwykle ponad 3-krotnie (a w większych projektach i monorepozytoriach nawet bardziej), co codziennie usprawnia procesy deweloperskie i budowanie w CI.

W Metro 0.82 wprowadzamy również stabilną obsługę pól "exports" i "imports" w package.json. Rozpoznawanie "exports" zostało wprowadzone w React Native 0.72, a wsparcie dla "imports" dodano dzięki wkładowi społeczności - obie funkcje będą teraz domyślnie włączone we wszystkich projektach korzystających z React Native 0.79.
To poprawia kompatybilność z nowoczesnymi zależnościami npm i otwiera nowe, zgodne ze standardami sposoby organizowania projektów.
Chociaż testowaliśmy "exports" w package.json w społeczności od jakiegoś czasu, to przejście może być zmianą łamiącą kompatybilność dla niektórych pakietów i konfiguracji projektów.
W szczególności wiemy o zgłoszonych przez użytkowników problemach z kompatybilnością dla popularnych pakietów, takich jak Firebase i AWS Amplify, i pracujemy nad ich naprawą u źródła.
Jeśli napotkasz problemy:
- Zaktualizuj do poprawki Metro 0.81.5 lub ustaw
resolver.unstable_enablePackageExports = false, aby zrezygnować z funkcji. - Zobacz expo/expo#36551 dla listy dotkniętych pakietów i przyszłych aktualizacji.
Przeniesienie JSC do pakietu społecznościowego
W ramach naszych starań o zmniejszenie powierzchni API React Native, przenosimy silnik JavaScriptCore (JSC) do pakietu utrzymywanego przez społeczność: @react-native-community/javascriptcore
Ta zmiana nie wpłynie na użytkowników korzystających z Hermesa.
Począwszy od React Native 0.79, możesz używać wersji JSC wspieranej przez społeczność, postępując zgodnie z instrukcjami instalacji w readme. Wersja JSC dostarczana z rdzeniem React Native pozostanie dostępna w wersji 0.79, ale planujemy jej usunięcie w najbliższej przyszłości.
Przeniesienie JSC do pakietu utrzymywanego przez społeczność pozwoli nam częściej aktualizować jego wersję i oferować najnowsze funkcje. Wersja JSC wspierana przez społeczność będzie miała osobny harmonogram wydań niż React Native.
iOS: Rejestracja natywnych modułów kompatybilnych ze Swiftem
W tym wydaniu modernizujemy sposób rejestrowania natywnych modułów w środowisku wykonawczym React Native. Nowe podejście jest zgodne z metodą opisaną w oficjalnej dokumentacji.
Począwszy od tej wersji React Native, możesz rejestrować moduły poprzez modyfikację pliku package.json. Wprowadziliśmy nowe pole modulesProvider we właściwości ios:
"codegenConfig": {
"ios": {
+ "modulesProvider": {
+ "JS Name for the module": "ObjC Module provider for the pure C++ TM or a class conforming to RCTTurboModule"
+ }
}
}
Codegen automatycznie wygeneruje odpowiedni kod na podstawie twojego pliku package.json.
Jeśli używasz czystego natywnego modułu C++, powinieneś zastosować tę zalecaną konfigurację:
Configure pure C++Native Modules in your app
For pure C++ Native Modules, you need to add a new ObjectiveC++ class to glue together the C++ Native Module with the rest of the App:
#import <Foundation/Foundation.h>
#import <ReactCommon/RCTTurboModule.h>
NS_ASSUME_NONNULL_BEGIN
@interface <YourNativeModule>Provider : NSObject <RCTModuleProvider>
@end
NS_ASSUME_NONNULL_END
#import "<YourNativeModule>Provider.h"
#import <ReactCommon/CallInvoker.h>
#import <ReactCommon/TurboModule.h>
#import "<YourNativeModule>.h"
@implementation NativeSampleModuleProvider
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeSampleModule>(params.jsInvoker);
}
To nowe podejście ujednolica rejestrację natywnych modułów zarówno dla twórców aplikacji, jak i bibliotek. Biblioteki mogą określić te same właściwości w swoim package.json, a Codegen zajmie się resztą.
Rozwiązuje to ograniczenie wprowadzone w wersji 0.77, które uniemożliwiało rejestrację czystego natywnego modułu C++ ze Swiftowym AppDelegate. Jak widać, żadna z tych zmian nie modyfikuje AppDelegate, a wygenerowany kod będzie działać zarówno dla AppDelegate napisanego w Swift, jak i Objective-C.
Android: Szybsze uruchamianie aplikacji
Dostarczamy również zmianę, która znacząco poprawi czas uruchamiania aplikacji na Androida.
Począwszy od tej wersji, przestaniemy kompresować pakiet JavaScript wewnątrz APK. Wcześniej system Android musiał dekompresować pakiet JavaScript przed uruchomieniem aplikacji, co powodowało znaczące spowolnienie podczas startu.
Od tego wydania domyślnie dostarczamy pakiet JavaScript bez kompresji, dzięki czemu twoje aplikacje na Androida będą uruchamiać się szybciej.
Zespół Margelo przetestował tę funkcję w aplikacji Discord i uzyskał znaczący wzrost wydajności: czas do interaktywności (TTI) Discorda skrócił się o 400 ms, co oznacza 12% przyspieszenie przy zmianie jednej linii kodu (test na Samsungu A14).
Z drugiej strony, przechowywanie niekompresowanego pakietu zwiększy zużycie miejsca przez aplikację na urządzeniu użytkownika. Jeśli to problem, możesz kontrolować to zachowanie za pomocą właściwości enableBundleCompression w pliku app/build.gradle.
react {
// ...
// If you want to compress the JS bundle (slower startup, less
// space consumption)
enableBundleCompression = true
// If don't you want to compress the JS bundle (faster startup,
// higher space consumption)
enableBundleCompression = false
// Default is `false`
}
Pamiętaj, że rozmiar APK wzrośnie w tym wydaniu, ale użytkownicy nie poniosą dodatkowych kosztów związanych z rozmiarem pobieranego APK, ponieważ pliki APK są kompresowane podczas pobierania z sieci.
Zmiany łamiące kompatybilność
Usunięcie zdalnego debugowania JS
W ramach naszych starań o poprawę debugowania, usuwamy zdalne debugowanie JS przez Chrome. Ta przestarzała metoda była przestarzała od wersji React Native 0.73. Używaj React Native DevTools do nowoczesnego i niezawodnego debugowania.
Oznacza to również, że React Native nie jest już kompatybilny z projektem społecznościowym react-native-debugger. Deweloperom, którzy chcą używać rozszerzeń debugujących innych firm, takich jak Redux DevTools, polecamy Expo DevTools Plugins lub integrację samodzielnych wersji tych narzędzi.
Więcej informacji znajdziesz w dedykowanym poście.
Aktualizacja modułów wewnętrznych do składni export
W ramach modernizacji naszego kodu JavaScript, zaktualizowaliśmy wiele modułów implementacyjnych w react-native, aby konsekwentnie używały składni export zamiast module.exports.
Zaktualizowaliśmy około 46 interfejsów API w sumie, które można znaleźć w dzienniku zmian.
Ta zmiana ma subtelny wpływ na istniejące importy:
Case 1: Default export
// CHANGED - require() syntax
- const ImageBackground = require('react-native/Libraries/Image/ImageBackground');
+ const ImageBackground = require('react-native/Libraries/Image/ImageBackground').default;
// Unchanged - import syntax
import ImageBackground from 'react-native/Libraries/Image/ImageBackground';
// RECOMMENDED - root import
import {ImageBackground} from 'react-native';
Case 2: Secondary exports
There are very few cases of this pattern, again unaffected when using the root 'react-native' import.
// Unchanged - require() syntax
const BlobRegistry = require('react-native/Libraries/Blob/BlobRegistry');
// Unchanged - require() syntax with destructuring
const {register, unregister} = require('react-native/Libraries/Blob/BlobRegistry');
// CHANGED - import syntax as single object
- import BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
+ import * as BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
// Unchanged - import syntax with destructuring
import {register, unregister} from 'react-native/Libraries/Blob/BlobRegistry';
// RECOMMENDED - root import
import {BlobRegistry} from 'react-native';
Oczekujemy, że wpływ tej zmiany będzie bardzo ograniczony, szczególnie w projektach pisanych w TypeScript i używających składni import. Sprawdź, czy nie ma błędów typów i zaktualizuj swój kod.
Zaleca się importowanie z głównej ścieżki react-native
Podsumowując, zdecydowanie zalecamy importowanie z głównej ścieżki 'react-native', aby uniknąć dodatkowych zmian łamiących kompatybilność w przyszłości. W następnej wersji zaniechamy głębokich importów jako część lepszego definiowania publicznego API JavaScript React Native (zobacz RFC).
Inne zmiany łamiące kompatybilność
Ta lista zawiera szereg innych zmian łamiących kompatybilność, które mogą mieć niewielki wpływ na kod twojej aplikacji i warto o nich wspomnieć.
-
Nieprawidłowe długości bez jednostek w cieniach i filtrach:
- Aby React Native był bardziej zgodny ze specyfikacją CSS/Web, nie obsługujemy już długości bez jednostek w
box-shadowifilter. Oznacza to, że jeśli używałeśbox-shadoww postaci1 1 black, nie będzie on renderowany. Zamiast tego należy podać jednostki, np.1px 1px black
- Aby React Native był bardziej zgodny ze specyfikacją CSS/Web, nie obsługujemy już długości bez jednostek w
-
Usunięcie niepoprawnej składni hwb() z normalize-color:
- Aby React Native był bardziej zgodny ze specyfikacją CSS/Web, ograniczamy niektóre nieprawidłowe składnie dla
hwb(). Historycznie React Native obsługiwał wartości oddzielone przecinkami (np.hwb(0, 0%, 100%)), których teraz nie obsługujemy (należy migrować dohwb(0 0% 100%)). Więcej informacji o tej zmianie można znaleźć tutaj.
- Aby React Native był bardziej zgodny ze specyfikacją CSS/Web, ograniczamy niektóre nieprawidłowe składnie dla
-
Aktualizacja eksportów w Libraries/Core/ExceptionsManager
- W ramach modernizacji interfejsu API JavaScript React Native zaktualizowaliśmy
ExceptionsManager, który teraz eksportuje domyślny obiektExceptionsManagerorazSyntheticErrorjako eksport dodatkowy.
- W ramach modernizacji interfejsu API JavaScript React Native zaktualizowaliśmy
Podziękowania
React Native 0.79 zawiera ponad 944 commity od 100 współtwórców. Dziękujemy za waszą ciężką pracę!
Chcielibyśmy podziękować tym członkom społeczności, którzy wnieśli znaczący wkład w tę wersję:
-
Marc Rousavy za opracowanie i udokumentowanie funkcji „Android: Szybsze uruchamianie aplikacji”
-
Kudo Chien i Oskar Kwaśniewski za pracę nad pakietem
@react-native-community/javascriptcorei napisanie sekcji „Przeniesienie JSC do pakietu społecznościowego” -
James Lawson za dodanie obsługi rozdzielczości podścieżek importu w Metro.
Dziękujemy również dodatkowym autorom, którzy pracowali nad dokumentacją funkcji w tym poście:
-
Rob Hogan za sekcję „Nowe funkcje Metro”
-
Alex Hunt za sekcje „Usunięcie zdalnego debugowania JS” i „Aktualizacja modułów wewnętrznych do składni export”
-
Riccardo Cipolleschi za pracę nad rejestracją natywnych modułów w iOS
Aktualizacja do wersji 0.79
Do sprawdzenia zmian w kodzie między wersjami React Native w istniejących projektach, oprócz dokumentacji aktualizacji, użyj React Native Upgrade Helper.
Aby utworzyć nowy projekt:
npx @react-native-community/cli@latest init MyProject --version latest
Jeśli korzystasz z Expo, React Native 0.79 będzie obsługiwany w nadchodzącym Expo SDK 53 jako domyślna wersja React Native.
Wersja 0.79 jest teraz najnowszą stabilną wersją React Native, a wersja 0.76.x przestaje być obsługiwana. Więcej informacji znajdziesz w polityce wsparcia React Native. Planujemy opublikować ostatnią aktualizację kończącą cykl życia wersji 0.76 w najbliższym czasie.


