From 010d7cd5dcb9796024100ea9215e0baf7bb8ccd9 Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Tue, 6 Sep 2022 06:02:01 -0300 Subject: [PATCH 01/88] TextInput: Add readOnly prop (#3278) --- docs/textinput.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/textinput.md b/docs/textinput.md index c685e65d14c..6e831a04d12 100644 --- a/docs/textinput.md +++ b/docs/textinput.md @@ -625,6 +625,16 @@ The text color of the placeholder string. --- +### `readOnly` + +If `true`, text is not editable. The default value is `false`. + +| Type | +| ---- | +| bool | + +--- + ### `returnKeyLabel`
Android
Sets the return key to the label. Use it instead of `returnKeyType`. From 51a75437cd08bbe34d07cf2be10be70842dcd331 Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Tue, 6 Sep 2022 06:04:49 -0300 Subject: [PATCH 02/88] AccessibilityInfo: add prefersCrossFadeTransitions to docs (#3279) --- docs/accessibilityinfo.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/accessibilityinfo.md b/docs/accessibilityinfo.md index 3d0555520b1..39fe88bcf58 100644 --- a/docs/accessibilityinfo.md +++ b/docs/accessibilityinfo.md @@ -210,7 +210,7 @@ Post a string to be announced by the screen reader with modification options. By static getRecommendedTimeoutMillis(originalTimeout) ``` -Gets the timeout in millisecond that the user needs. +Gets the timeout in millisecond that the user needs. This value is set in "Time to take action (Accessibility timeout)" of "Accessibility" settings. **Parameters:** @@ -293,6 +293,16 @@ Query whether a screen reader is currently enabled. Returns a promise which reso --- +### `prefersCrossFadeTransitions()`
iOS
+ +```jsx +static prefersCrossFadeTransitions() +``` + +Query whether reduce motion and prefer cross-fade transitions settings are currently enabled. Returns a promise which resolves to a boolean. The result is `true` when prefer cross-fade transitions is enabled and `false` otherwise. + +--- + ### `removeEventListener()` ```jsx From 9a4ad7aaa04706a61ea128d6bfe4448132f8336b Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Tue, 6 Sep 2022 06:08:25 -0300 Subject: [PATCH 03/88] TextInput: Add rows prop (#3280) --- docs/textinput.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/textinput.md b/docs/textinput.md index 6e831a04d12..f9b6e33008b 100644 --- a/docs/textinput.md +++ b/docs/textinput.md @@ -691,6 +691,16 @@ If `true`, allows TextInput to pass touch events to the parent component. This a --- +### `rows`
Android
+ +Sets the number of lines for a `TextInput`. Use it with multiline set to `true` to be able to fill the lines. + +| Type | +| ------ | +| number | + +--- + ### `scrollEnabled`
iOS
If `false`, scrolling of the text view will be disabled. The default value is `true`. Only works with `multiline={true}`. From 04250d6c0a173edccd5decf93c56f22678a0deee Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Tue, 6 Sep 2022 06:18:34 -0300 Subject: [PATCH 04/88] TextInput: Add inputMode prop (#3289) --- docs/textinput.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/textinput.md b/docs/textinput.md index f9b6e33008b..7946e591a82 100644 --- a/docs/textinput.md +++ b/docs/textinput.md @@ -373,6 +373,27 @@ An optional identifier which links a custom [InputAccessoryView](inputaccessoryv --- +### `inputMode` + +Works like the `inputmode` attribute in HTML, it determines which keyboard to open, e.g. `numeric` and has precedence over `keyboardType`. + +Support the following values: + +- `none` +- `text` +- `decimal` +- `numeric` +- `tel` +- `search` +- `email` +- `url` + +| Type | +| --------------------------------------------------------------------------- | +| enum('decimal', 'email', 'none', 'numeric', 'search', 'tel', 'text', 'url') | + +--- + ### `keyboardAppearance`
iOS
Determines the color of the keyboard. From 0de9633e56b3079af82ffd2a000ac4a88ab66c34 Mon Sep 17 00:00:00 2001 From: EvertEt Date: Tue, 6 Sep 2022 11:22:19 +0200 Subject: [PATCH 05/88] Flexbox: correct example description (#3284) --- docs/flexbox.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/flexbox.md b/docs/flexbox.md index 4ba10df006b..f4b44da084c 100644 --- a/docs/flexbox.md +++ b/docs/flexbox.md @@ -16,7 +16,7 @@ The defaults are different, with `flexDirection` defaulting to `column` instead [`flex`](layout-props#flex) will define how your items are going to **“fill”** over the available space along your main axis. Space will be divided according to each element's flex property. -In the following example, the red, yellow, and green views are all children in the container view that has `flex: 1` set. The red view uses `flex: 1` , the yellow view uses `flex: 2`, and the green view uses `flex: 3` . **1+2+3 = 6**, which means that the red view will get `1/6` of the space, the yellow `2/6` of the space, and the green `3/6` of the space. +In the following example, the red, orange, and green views are all children in the container view that has `flex: 1` set. The red view uses `flex: 1` , the orange view uses `flex: 2`, and the green view uses `flex: 3` . **1+2+3 = 6**, which means that the red view will get `1/6` of the space, the orange `2/6` of the space, and the green `3/6` of the space. ```SnackPlayer name=Flex%20Example import React from "react"; From 9422060674dc1347df8494e882ebba358d48db9a Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Tue, 6 Sep 2022 17:29:42 +0800 Subject: [PATCH 06/88] adding accessibilityRole 'grid' to documentation (#3224) --- docs/accessibility.md | 1 + docs/view.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/accessibility.md b/docs/accessibility.md index 17f444c3552..30f4d743c6c 100644 --- a/docs/accessibility.md +++ b/docs/accessibility.md @@ -161,6 +161,7 @@ In the above example method `addOne` changes the state variable `count`. As soon - **timer** Used to represent a timer. - **togglebutton** Used to represent a toggle button. Should be used with accessibilityState checked to indicate if the button is toggled on or off. - **toolbar** Used to represent a tool bar (a container of action buttons or components). +- **grid** Used with ScrollView, VirtualizedList, FlatList, or SectionList to represent a grid. Adds the in/out of grid announcements to the android GridView. ### `accessibilityState` diff --git a/docs/view.md b/docs/view.md index 687058cb68f..1d8462bdb0f 100644 --- a/docs/view.md +++ b/docs/view.md @@ -199,6 +199,7 @@ See the [Android `View` docs](http://developer.android.com/reference/android/vie - `'tablist'` - Used to represent a list of tabs. - `'timer'` - Used to represent a timer. - `'toolbar'` - Used to represent a tool bar (a container of action buttons or components). +- `'grid'` - Used with ScrollView, VirtualizedList, FlatList, or SectionList to represent a grid. Adds the in/out of grid announcements to the android GridView. | Type | | ------ | From 7d7f4831fd33c0f889f60cc05c6862171f136056 Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Tue, 6 Sep 2022 09:35:28 -0300 Subject: [PATCH 07/88] View: Add tabIndex prop (#3286) Co-authored-by: Bartosz Kaszubowski --- docs/view.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/view.md b/docs/view.md index 1d8462bdb0f..6be5e2864ac 100644 --- a/docs/view.md +++ b/docs/view.md @@ -610,6 +610,20 @@ Rasterization incurs an off-screen drawing pass and the bitmap consumes memory. --- +### `tabIndex`
Android
+ +Whether this `View` should be focusable with a non-touch input device, eg. receive focus with a hardware keyboard. +Supports the following values: + +- `0` - View is focusable +- `-1` - View is not focusable + +| Type | +| ----------- | +| enum(0, -1) | + +--- + ### `testID` Used to locate this view in end-to-end tests. From f57ac2d6b11b098800c19cdf3b41449b3de90784 Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Tue, 6 Sep 2022 09:36:40 -0300 Subject: [PATCH 08/88] Image: Add tintColor prop (#3292) Co-authored-by: Bartosz Kaszubowski --- docs/image.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/image.md b/docs/image.md index 82c8349770f..f1306f49a2f 100644 --- a/docs/image.md +++ b/docs/image.md @@ -446,6 +446,14 @@ A unique identifier for this element to be used in UI Automation testing scripts | ------ | | string | +### `tintColor` + +Changes the color of all non-transparent pixels to the `tintColor`. + +| Type | +| ------------------ | +| [color](colors.md) | + ## Methods ### `abortPrefetch()`
Android
From b4320925c492915510ee35179f711bba4e85c726 Mon Sep 17 00:00:00 2001 From: Daksh Bhardwaj Date: Tue, 6 Sep 2022 19:31:59 +0530 Subject: [PATCH 09/88] TextInput: Add enterKeyHint prop (#3299) --- docs/textinput.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/docs/textinput.md b/docs/textinput.md index 7946e591a82..9d09ee2211e 100644 --- a/docs/textinput.md +++ b/docs/textinput.md @@ -321,6 +321,30 @@ If `true`, the keyboard disables the return key when there is no text and automa --- +### `enterKeyHint` + +Determines what text should be shown to the return key. Has precedence over the `returnKeyType` prop. + +The following values work across platforms: + +- `enter` +- `done` +- `next` +- `search` +- `send` + +_Android Only_ + +The following values work on Android only: + +- `previous` + +| Type | +| ----------------------------------------------------------- | +| enum('enter', 'done', 'next', 'previous', 'search', 'send') | + +--- + ### `importantForAutofill`
Android
Tells the operating system whether the individual fields in your app should be included in a view structure for autofill purposes on Android API Level 26+. Possible values are `auto`, `no`, `noExcludeDescendants`, `yes`, and `yesExcludeDescendants`. The default value is `auto`. From 10f26e9e84514838f35faf80f29a209a5f47371d Mon Sep 17 00:00:00 2001 From: Ricky Date: Tue, 6 Sep 2022 13:00:59 -0400 Subject: [PATCH 10/88] Revert renaming native components (#3301) --- docs/intro-react-native-components.md | 14 +++++++------- docs/introduction.md | 4 ++-- .../version-0.70/intro-react-native-components.md | 14 +++++++------- .../versioned_docs/version-0.70/introduction.md | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/intro-react-native-components.md b/docs/intro-react-native-components.md index 00d22878aad..54eb7f69311 100644 --- a/docs/intro-react-native-components.md +++ b/docs/intro-react-native-components.md @@ -1,7 +1,7 @@ --- id: intro-react-native-components -title: Core Components and Fabric Components -description: 'React Native lets you compose app interfaces using Fabric Components. Conveniently, it comes with a set of these components for you to get started with right now—the Core Components!' +title: Core Components and Native Components +description: 'React Native lets you compose app interfaces using Native Components. Conveniently, it comes with a set of these components for you to get started with right now—the Core Components!' --- import ThemedImage from '@theme/ThemedImage'; @@ -17,17 +17,17 @@ In Android and iOS development, a **view** is the basic building block of UI: a
Just a sampling of the many views used in Android and iOS apps.
-## Fabric Components +## Native Components -In Android development, you write views in Kotlin or Java; in iOS development, you use Swift or Objective-C. With React Native, you can invoke these views with JavaScript using React components. At runtime, React Native creates the corresponding Android and iOS views for those components. Because React Native components are backed by the same views as Android and iOS, React Native apps look, feel, and perform like any other apps. We call these platform-backed components **Fabric Components.** [_Fabric_](architecture/fabric-renderer) is the name of the React Native renderer, therefore components that are rendered via Fabric are called Fabric Components. +In Android development, you write views in Kotlin or Java; in iOS development, you use Swift or Objective-C. With React Native, you can invoke these views with JavaScript using React components. At runtime, React Native creates the corresponding Android and iOS views for those components. Because React Native components are backed by the same views as Android and iOS, React Native apps look, feel, and perform like any other apps. We call these platform-backed components **Native Components.** -React Native comes with a set of essential, ready-to-use Fabric Components you can use to start building your app today. These are React Native's **Core Components**. +React Native comes with a set of essential, ready-to-use Native Components you can use to start building your app today. These are React Native's **Core Components**. -React Native also lets you build your own [Fabric Components](the-new-architecture/pillars-fabric-components) to suit your app’s unique needs. We also have a thriving ecosystem of these **community-contributed components.** Check out [Native Directory](https://reactnative.directory) to find what the community has been creating. +React Native also lets you build your own Native Components for [Android](native-components-android.md) and [iOS](native-components-ios.md) to suit your app’s unique needs. We also have a thriving ecosystem of these **community-contributed components.** Check out [Native Directory](https://reactnative.directory) to find what the community has been creating. ## Core Components -React Native has many Core Components for everything form controls to activity indicators. You can find them all [documented in the API section](components-and-apis). You will mostly work with the following Core Components: +React Native has many Core Components for everything from controls to activity indicators. You can find them all [documented in the API section](components-and-apis). You will mostly work with the following Core Components: | React Native UI Component | Android View | iOS View | Web Analog | Description | | ------------------------- | -------------- | ---------------- | ----------------------- | ----------------------------------------------------------------------------------------------------- | diff --git a/docs/introduction.md b/docs/introduction.md index 1e4c9abbdbe..f77b91adf9b 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -8,7 +8,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con

- Welcome to the very start of your React Native journey! If you're looking for environment setup instructions, they've moved to their own section. Continue reading for an introduction to the documentation, Fabric Components, React, and more! + Welcome to the very start of your React Native journey! If you're looking for environment setup instructions, they've moved to their own section. Continue reading for an introduction to the documentation, Native Components, React, and more!

@@ -136,4 +136,4 @@ Menu paths are written in bold and use carets to navigate submenus. Example: **A --- -Now that you know how this guide works, it's time to get to know the foundation of React Native: [Fabric Components](intro-react-native-components.md). +Now that you know how this guide works, it's time to get to know the foundation of React Native: [Native Components](intro-react-native-components.md). diff --git a/website/versioned_docs/version-0.70/intro-react-native-components.md b/website/versioned_docs/version-0.70/intro-react-native-components.md index 00d22878aad..54eb7f69311 100644 --- a/website/versioned_docs/version-0.70/intro-react-native-components.md +++ b/website/versioned_docs/version-0.70/intro-react-native-components.md @@ -1,7 +1,7 @@ --- id: intro-react-native-components -title: Core Components and Fabric Components -description: 'React Native lets you compose app interfaces using Fabric Components. Conveniently, it comes with a set of these components for you to get started with right now—the Core Components!' +title: Core Components and Native Components +description: 'React Native lets you compose app interfaces using Native Components. Conveniently, it comes with a set of these components for you to get started with right now—the Core Components!' --- import ThemedImage from '@theme/ThemedImage'; @@ -17,17 +17,17 @@ In Android and iOS development, a **view** is the basic building block of UI: a
Just a sampling of the many views used in Android and iOS apps.
-## Fabric Components +## Native Components -In Android development, you write views in Kotlin or Java; in iOS development, you use Swift or Objective-C. With React Native, you can invoke these views with JavaScript using React components. At runtime, React Native creates the corresponding Android and iOS views for those components. Because React Native components are backed by the same views as Android and iOS, React Native apps look, feel, and perform like any other apps. We call these platform-backed components **Fabric Components.** [_Fabric_](architecture/fabric-renderer) is the name of the React Native renderer, therefore components that are rendered via Fabric are called Fabric Components. +In Android development, you write views in Kotlin or Java; in iOS development, you use Swift or Objective-C. With React Native, you can invoke these views with JavaScript using React components. At runtime, React Native creates the corresponding Android and iOS views for those components. Because React Native components are backed by the same views as Android and iOS, React Native apps look, feel, and perform like any other apps. We call these platform-backed components **Native Components.** -React Native comes with a set of essential, ready-to-use Fabric Components you can use to start building your app today. These are React Native's **Core Components**. +React Native comes with a set of essential, ready-to-use Native Components you can use to start building your app today. These are React Native's **Core Components**. -React Native also lets you build your own [Fabric Components](the-new-architecture/pillars-fabric-components) to suit your app’s unique needs. We also have a thriving ecosystem of these **community-contributed components.** Check out [Native Directory](https://reactnative.directory) to find what the community has been creating. +React Native also lets you build your own Native Components for [Android](native-components-android.md) and [iOS](native-components-ios.md) to suit your app’s unique needs. We also have a thriving ecosystem of these **community-contributed components.** Check out [Native Directory](https://reactnative.directory) to find what the community has been creating. ## Core Components -React Native has many Core Components for everything form controls to activity indicators. You can find them all [documented in the API section](components-and-apis). You will mostly work with the following Core Components: +React Native has many Core Components for everything from controls to activity indicators. You can find them all [documented in the API section](components-and-apis). You will mostly work with the following Core Components: | React Native UI Component | Android View | iOS View | Web Analog | Description | | ------------------------- | -------------- | ---------------- | ----------------------- | ----------------------------------------------------------------------------------------------------- | diff --git a/website/versioned_docs/version-0.70/introduction.md b/website/versioned_docs/version-0.70/introduction.md index 1e4c9abbdbe..f77b91adf9b 100644 --- a/website/versioned_docs/version-0.70/introduction.md +++ b/website/versioned_docs/version-0.70/introduction.md @@ -8,7 +8,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con

- Welcome to the very start of your React Native journey! If you're looking for environment setup instructions, they've moved to their own section. Continue reading for an introduction to the documentation, Fabric Components, React, and more! + Welcome to the very start of your React Native journey! If you're looking for environment setup instructions, they've moved to their own section. Continue reading for an introduction to the documentation, Native Components, React, and more!

@@ -136,4 +136,4 @@ Menu paths are written in bold and use carets to navigate submenus. Example: **A --- -Now that you know how this guide works, it's time to get to know the foundation of React Native: [Fabric Components](intro-react-native-components.md). +Now that you know how this guide works, it's time to get to know the foundation of React Native: [Native Components](intro-react-native-components.md). From d9d4adb410e689f6e56167cd2c25765fc884a1b4 Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Wed, 7 Sep 2022 09:08:34 +0200 Subject: [PATCH 11/88] docs: fix path in script example (#3302) --- docs/new-architecture-library-ios.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/new-architecture-library-ios.md b/docs/new-architecture-library-ios.md index c5054bd6e8e..67a78515da1 100644 --- a/docs/new-architecture-library-ios.md +++ b/docs/new-architecture-library-ios.md @@ -50,7 +50,7 @@ While this generated native interface code **will not ship as part of your libra ```sh cd -node node_modules/react_native/scripts/generate-artifacts.js \ +node node_modules/react-native/scripts/generate-artifacts.js \ --path / \ --outputPath \ ``` From 000d5811452c859d49e528236abf3ad6bda30333 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 8 Sep 2022 09:49:49 +0100 Subject: [PATCH 12/88] Update New Architecture instructions to use CMake instead of Android.mk (#3304) --- docs/new-architecture-app-modules-android.md | 94 ++++--------------- docs/new-architecture-app-renderer-android.md | 2 +- docs/new-architecture-library-android.md | 1 + docs/the-new-architecture/pillars-codegen.md | 1 + .../pillars-turbomodule.md | 1 + .../new-architecture-app-modules-android.md | 94 ++++--------------- .../new-architecture-app-renderer-android.md | 2 +- .../new-architecture-library-android.md | 1 + 8 files changed, 42 insertions(+), 154 deletions(-) diff --git a/docs/new-architecture-app-modules-android.md b/docs/new-architecture-app-modules-android.md index d6dd904f477..b3e8fddfb7c 100644 --- a/docs/new-architecture-app-modules-android.md +++ b/docs/new-architecture-app-modules-android.md @@ -32,30 +32,20 @@ android { // Add this block externalNativeBuild { - ndkBuild { - arguments "APP_PLATFORM=android-21", - "APP_STL=c++_shared", - "NDK_TOOLCHAIN_VERSION=clang", - "GENERATED_SRC_DIR=$buildDir/generated/source", - "PROJECT_BUILD_DIR=$buildDir", - "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", - "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", - "NODE_MODULES_DIR=$rootDir/../node_modules" - cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1" - cppFlags "-std=c++17" - targets "myapplication_appmodules" - // Fix for windows limit on number of character in file paths and in command lines - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - arguments "NDK_APP_SHORT_COMMANDS=true" - } + cmake { + arguments "-DPROJECT_BUILD_DIR=$buildDir", + "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", + "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", + "-DNODE_MODULES_DIR=$rootDir/../node_modules", + "-DANDROID_STL=c++_shared" } } } // Add this block externalNativeBuild { - ndkBuild { - path "$projectDir/src/main/jni/Android.mk" + cmake { + path "$projectDir/src/main/jni/CMakeLists.txt" } } } @@ -77,8 +67,8 @@ android { afterEvaluate { preBuild.dependsOn(packageReactNdkLibs) - configureNdkBuildDebug.dependsOn(preBuild) - configureNdkBuildRelease.dependsOn(preBuild) + configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild) + configureCMakeDebug.dependsOn(preDebugBuild) } packagingOptions { @@ -88,64 +78,16 @@ android { } ``` -Finally, we need to create a Makefile inside the `src/main/jni` folder called `Android.mk` with the following content: +Finally, we need to create a CMake file inside the `src/main/jni` folder called `CMakeLists.txt` with the following content: -```makefile -THIS_DIR := $(call my-dir) +```cmake +cmake_minimum_required(VERSION 3.13) -include $(REACT_ANDROID_DIR)/Android-prebuilt.mk +# Define the library name here. +project(myapplication_appmodules) -# If you wish to add a custom TurboModule or Fabric component in your app you -# will have to include the following autogenerated makefile. -# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk - -# Includes the MK file for autolinked libraries -include $(PROJECT_BUILD_DIR)/generated/rncli/src/main/jni/Android-rncli.mk - -include $(CLEAR_VARS) - -LOCAL_PATH := $(THIS_DIR) - -# You can customize the name of your application .so file here. -LOCAL_MODULE := awesomeapp_appmodules - -LOCAL_C_INCLUDES := $(LOCAL_PATH) $(PROJECT_BUILD_DIR)/generated/rncli/src/main/jni -LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(PROJECT_BUILD_DIR)/generated/rncli/src/main/jni/*.cpp) -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(PROJECT_BUILD_DIR)/generated/rncli/src/main/jni - -# If you wish to add a custom TurboModule or Fabric component in your app you -# will have to uncomment those lines to include the generated source -# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni) -# -# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni -# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) -# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni - -# Here you should add any native library you wish to depend on. -LOCAL_SHARED_LIBRARIES := \ -libfabricjni \ -libfbjni \ -libfolly_runtime \ -libglog \ -libjsi \ -libreact_codegen_rncore \ -libreact_debug \ -libreact_nativemodule_core \ -libreact_render_componentregistry \ -libreact_render_core \ -libreact_render_debug \ -libreact_render_graphics \ -librrc_view \ -libruntimeexecutor \ -libturbomodulejsijni \ -libyoga - -# Autolinked libraries -LOCAL_SHARED_LIBRARIES += $(call import-codegen-modules) - -LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 - -include $(BUILD_SHARED_LIBRARY) +# This file includes all the necessary to let you build your application with the New Architecture. +include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake) ``` This setup will run a native build on your project and will compile the C++ files that have been generated by the codegen. You will see the native build running with the Gradle task `:app:externalNativeBuildDebug` @@ -249,7 +191,7 @@ protected constructor( -Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `LOCAL_MODULE :=` inside the `Android.mk` file you created before. +Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `project()` inside the `CMakeLists.txt` file you created before. This class will then be responsible of loading the TurboModules and will take care of loading the native library build with the NDK at runtime. diff --git a/docs/new-architecture-app-renderer-android.md b/docs/new-architecture-app-renderer-android.md index 4b7bbe88b04..736abcb8f56 100644 --- a/docs/new-architecture-app-renderer-android.md +++ b/docs/new-architecture-app-renderer-android.md @@ -113,7 +113,7 @@ LOG Running "App" with {"fabric":true,"initialProps":{},"rootTag":1} ## Migrating Android ViewManagers -First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the Makefile (`Android.mk`) and other native builds setup steps are presented over there and won’t be repeated here. +First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. ### JavaScript changes diff --git a/docs/new-architecture-library-android.md b/docs/new-architecture-library-android.md index 565546a12d0..09f1ee2fb7f 100644 --- a/docs/new-architecture-library-android.md +++ b/docs/new-architecture-library-android.md @@ -34,6 +34,7 @@ app/build/generated/source/codegen │ └── NativeAwesomeManagerSpec.java ├── jni │ ├── Android.mk +│ ├── CMakeLists.txt │ ├── react │ │ └── renderer │ │ └── components diff --git a/docs/the-new-architecture/pillars-codegen.md b/docs/the-new-architecture/pillars-codegen.md index c55db88d267..11bd5062190 100644 --- a/docs/the-new-architecture/pillars-codegen.md +++ b/docs/the-new-architecture/pillars-codegen.md @@ -162,6 +162,7 @@ codegen │ └── MyTurbomodule.java ├── jni │ ├── Android.mk +│ ├── CMakeLists.txt │ ├── MyTurbomodule-generated.cpp │ ├── MyTurbomodule.h │ └── react diff --git a/docs/the-new-architecture/pillars-turbomodule.md b/docs/the-new-architecture/pillars-turbomodule.md index 9ccd7a9820f..77159a4fc24 100644 --- a/docs/the-new-architecture/pillars-turbomodule.md +++ b/docs/the-new-architecture/pillars-turbomodule.md @@ -497,6 +497,7 @@ codegen │ └── NativeCalculatorSpec.java ├── jni │ ├── Android.mk +│ ├── CMakeLists.txt │ ├── RTNCalculator-generated.cpp │ ├── RTNCalculator.h │ └── react diff --git a/website/versioned_docs/version-0.70/new-architecture-app-modules-android.md b/website/versioned_docs/version-0.70/new-architecture-app-modules-android.md index d6dd904f477..b3e8fddfb7c 100644 --- a/website/versioned_docs/version-0.70/new-architecture-app-modules-android.md +++ b/website/versioned_docs/version-0.70/new-architecture-app-modules-android.md @@ -32,30 +32,20 @@ android { // Add this block externalNativeBuild { - ndkBuild { - arguments "APP_PLATFORM=android-21", - "APP_STL=c++_shared", - "NDK_TOOLCHAIN_VERSION=clang", - "GENERATED_SRC_DIR=$buildDir/generated/source", - "PROJECT_BUILD_DIR=$buildDir", - "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", - "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", - "NODE_MODULES_DIR=$rootDir/../node_modules" - cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1" - cppFlags "-std=c++17" - targets "myapplication_appmodules" - // Fix for windows limit on number of character in file paths and in command lines - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - arguments "NDK_APP_SHORT_COMMANDS=true" - } + cmake { + arguments "-DPROJECT_BUILD_DIR=$buildDir", + "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", + "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", + "-DNODE_MODULES_DIR=$rootDir/../node_modules", + "-DANDROID_STL=c++_shared" } } } // Add this block externalNativeBuild { - ndkBuild { - path "$projectDir/src/main/jni/Android.mk" + cmake { + path "$projectDir/src/main/jni/CMakeLists.txt" } } } @@ -77,8 +67,8 @@ android { afterEvaluate { preBuild.dependsOn(packageReactNdkLibs) - configureNdkBuildDebug.dependsOn(preBuild) - configureNdkBuildRelease.dependsOn(preBuild) + configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild) + configureCMakeDebug.dependsOn(preDebugBuild) } packagingOptions { @@ -88,64 +78,16 @@ android { } ``` -Finally, we need to create a Makefile inside the `src/main/jni` folder called `Android.mk` with the following content: +Finally, we need to create a CMake file inside the `src/main/jni` folder called `CMakeLists.txt` with the following content: -```makefile -THIS_DIR := $(call my-dir) +```cmake +cmake_minimum_required(VERSION 3.13) -include $(REACT_ANDROID_DIR)/Android-prebuilt.mk +# Define the library name here. +project(myapplication_appmodules) -# If you wish to add a custom TurboModule or Fabric component in your app you -# will have to include the following autogenerated makefile. -# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk - -# Includes the MK file for autolinked libraries -include $(PROJECT_BUILD_DIR)/generated/rncli/src/main/jni/Android-rncli.mk - -include $(CLEAR_VARS) - -LOCAL_PATH := $(THIS_DIR) - -# You can customize the name of your application .so file here. -LOCAL_MODULE := awesomeapp_appmodules - -LOCAL_C_INCLUDES := $(LOCAL_PATH) $(PROJECT_BUILD_DIR)/generated/rncli/src/main/jni -LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(PROJECT_BUILD_DIR)/generated/rncli/src/main/jni/*.cpp) -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(PROJECT_BUILD_DIR)/generated/rncli/src/main/jni - -# If you wish to add a custom TurboModule or Fabric component in your app you -# will have to uncomment those lines to include the generated source -# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni) -# -# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni -# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) -# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni - -# Here you should add any native library you wish to depend on. -LOCAL_SHARED_LIBRARIES := \ -libfabricjni \ -libfbjni \ -libfolly_runtime \ -libglog \ -libjsi \ -libreact_codegen_rncore \ -libreact_debug \ -libreact_nativemodule_core \ -libreact_render_componentregistry \ -libreact_render_core \ -libreact_render_debug \ -libreact_render_graphics \ -librrc_view \ -libruntimeexecutor \ -libturbomodulejsijni \ -libyoga - -# Autolinked libraries -LOCAL_SHARED_LIBRARIES += $(call import-codegen-modules) - -LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 - -include $(BUILD_SHARED_LIBRARY) +# This file includes all the necessary to let you build your application with the New Architecture. +include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake) ``` This setup will run a native build on your project and will compile the C++ files that have been generated by the codegen. You will see the native build running with the Gradle task `:app:externalNativeBuildDebug` @@ -249,7 +191,7 @@ protected constructor( -Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `LOCAL_MODULE :=` inside the `Android.mk` file you created before. +Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `project()` inside the `CMakeLists.txt` file you created before. This class will then be responsible of loading the TurboModules and will take care of loading the native library build with the NDK at runtime. diff --git a/website/versioned_docs/version-0.70/new-architecture-app-renderer-android.md b/website/versioned_docs/version-0.70/new-architecture-app-renderer-android.md index 4b7bbe88b04..736abcb8f56 100644 --- a/website/versioned_docs/version-0.70/new-architecture-app-renderer-android.md +++ b/website/versioned_docs/version-0.70/new-architecture-app-renderer-android.md @@ -113,7 +113,7 @@ LOG Running "App" with {"fabric":true,"initialProps":{},"rootTag":1} ## Migrating Android ViewManagers -First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the Makefile (`Android.mk`) and other native builds setup steps are presented over there and won’t be repeated here. +First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. ### JavaScript changes diff --git a/website/versioned_docs/version-0.70/new-architecture-library-android.md b/website/versioned_docs/version-0.70/new-architecture-library-android.md index 565546a12d0..09f1ee2fb7f 100644 --- a/website/versioned_docs/version-0.70/new-architecture-library-android.md +++ b/website/versioned_docs/version-0.70/new-architecture-library-android.md @@ -34,6 +34,7 @@ app/build/generated/source/codegen │ └── NativeAwesomeManagerSpec.java ├── jni │ ├── Android.mk +│ ├── CMakeLists.txt │ ├── react │ │ └── renderer │ │ └── components From 9e6e3116966e2b9ba6208bfd8ff2bb19ccff1983 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 8 Sep 2022 12:55:43 +0100 Subject: [PATCH 13/88] Follow-up on CMake clarification for 0.70 (#3309) --- .../version-0.70/the-new-architecture/pillars-codegen.md | 1 + .../version-0.70/the-new-architecture/pillars-turbomodule.md | 1 + 2 files changed, 2 insertions(+) diff --git a/website/versioned_docs/version-0.70/the-new-architecture/pillars-codegen.md b/website/versioned_docs/version-0.70/the-new-architecture/pillars-codegen.md index c55db88d267..11bd5062190 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/pillars-codegen.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/pillars-codegen.md @@ -162,6 +162,7 @@ codegen │ └── MyTurbomodule.java ├── jni │ ├── Android.mk +│ ├── CMakeLists.txt │ ├── MyTurbomodule-generated.cpp │ ├── MyTurbomodule.h │ └── react diff --git a/website/versioned_docs/version-0.70/the-new-architecture/pillars-turbomodule.md b/website/versioned_docs/version-0.70/the-new-architecture/pillars-turbomodule.md index 9ccd7a9820f..77159a4fc24 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/pillars-turbomodule.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/pillars-turbomodule.md @@ -497,6 +497,7 @@ codegen │ └── NativeCalculatorSpec.java ├── jni │ ├── Android.mk +│ ├── CMakeLists.txt │ ├── RTNCalculator-generated.cpp │ ├── RTNCalculator.h │ └── react From 7c1091c6e37f60fc9d83d2da67cdb80a5934ba92 Mon Sep 17 00:00:00 2001 From: Arati Chilad <58401542+arati-1@users.noreply.github.com> Date: Thu, 8 Sep 2022 09:19:13 -0700 Subject: [PATCH 14/88] The New Architecture section editorial review (#3288) * [Do Not Merge] Refactoring The New Architecture (#3029) * [Guide - The New Architecture] What Backward Compatibility Is (#3038) * Guide to creating a New Architecture app from template (#3056) * Start new template guide This is a first iteration. I want to get feedback on a few aspects, so starting from here as a baseline. * Update title * Use tabs for target OS Set up matching the style of "Getting Started", except I kept the headers inside the tabs for now as it makes for a useful right-hand TOC. * Capitalize New Architecture, simplify * Preliminary section for Hermes Add section for recommending enabling Hermes. Not sure of contents yet, and still have to test. * Reword to emphasize importance of Hermes usage * Show new arch in use * Add build speed article link * Add pro tip for pod install alias * Restructure, repeat less Favor linking to original setup guide instead of repeating content. * Note about Expo * Include command on uninstalling global CLI * How to learn more * Remove headers in tabs They don't work correctly with the righthand TOC. * Make header more clear * Use quote block less often There was way too much yellow. * Opt for instructions using XCode Because `xcodebuild clean` already failed me once when XCode GUI clean worked. * Fix lint issue * Improve wording * Use product name * Fix line wraps * Reword based on feedback * Note use of bundle install * Pod removal instructions Also standardize on using yarn scripts from template for commands, it's a little confusing to see the mix of `npx` and `yarn` once we start referring to `yarn pod-install` * Convert quotes to admonitions * Convert Note: to admonitions * Feedback: Change admonitions to caution * PR feedback * New Architecture landing page (#3072) * First draft of landing page * Add migration and backwards compatibility links * lint fix * Restructure slightly, leaning more on context from Why a New Architecture * Don't need md in links * Suggested rewording * Rephrase pillar summaries * [Guide - The New Architecture] Why A New Architecture (#3043) * [Guide - The New Architecture] Pillars (#3046) * [Guide - The New Architecture] TurboModules as Native Modules (#3039) * [Guide - The New Architecture] Fabric Components as Native Components (#3040) * [FEAT][TNA] Fabric Component Guide (#3132) * [Feat] Add intro for Fabric Components * feat: add guide to create a Fabric Component * Add page on codegen (#3155) * [FEAT] TurboModules guide (#3168) * [Feat] Add intro for Fabric Components * feat: add guide to create a Fabric Component * Beginning of guide/folder structure * WIP JS Spec * specification section * Configuration * native code intro * Must be named Spec * Best stab at iOS native code, but I don't know how to describe what's going on in the code very well. Extrapolated what I could. * Android instructions iOS isn't working for me. Builds, but can't load module. Writing up Android auto-linking next because the steps I tested did work. * Include linking instructions from RNNArch repo * Add example JavaScript * native modules link * Address quick feedback items * Remove, fix for rebased branch * fix TM parameter on Android * Revert to 'Codegen' casing * Revert folly version change 2021.07.22 is for current version on main * fix typo * getTurboModule explainer * Sentence edits - Fix acronym bolding - Change wording to "recommended" because "standard" has other connotations of possibly being required - Parentheses unnecessary, distracting * Remove TODO for now Getting inconsistent results here, not sure if this is wrong or not; removing TODO for now so it doesn't block anything * ABI rephrase, more in line with new Fabric guide wording * Explain shared C++ code more * feat: add guide to create a Fabric Component * feat: add guide to create a Fabric Component * package.json description * Lint fixes * fix: Move JS constants to reduce changes * fix: Remove newline * feat: add required step for Android Codegen * fix: use the proper links Co-authored-by: Riccardo Cipolleschi * wip: migration guide review (#3200) * Fix for some typos and other editorial related changes * Update docs/the-new-architecture/pillars-fabric-components.md correcting the article Co-authored-by: Riccardo * Update pillars-fabric-components.md Co-authored-by: Riccardo Co-authored-by: Lizzi Lindboe Co-authored-by: Riccardo --- docs/new-architecture-app-intro.md | 20 ++++---- docs/new-architecture-library-android.md | 14 +++--- docs/new-architecture-library-intro.md | 48 +++++++++---------- docs/new-architecture-library-ios.md | 12 ++--- ...ackward-compatibility-fabric-components.md | 22 ++++----- .../backward-compatibility-turbomodules.md | 24 +++++----- docs/the-new-architecture/landing-page.md | 12 ++--- docs/the-new-architecture/pillars-codegen.md | 42 ++++++++-------- .../pillars-fabric-components.md | 34 ++++++------- .../pillars-turbomodule.md | 30 ++++++------ docs/the-new-architecture/pillars.md | 8 ++-- docs/the-new-architecture/use-app-template.md | 20 ++++---- docs/the-new-architecture/why.md | 30 ++++++------ 13 files changed, 158 insertions(+), 158 deletions(-) diff --git a/docs/new-architecture-app-intro.md b/docs/new-architecture-app-intro.md index dc7948d4dff..2b872ced579 100644 --- a/docs/new-architecture-app-intro.md +++ b/docs/new-architecture-app-intro.md @@ -9,11 +9,11 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; There are a few prerequisites that should be addressed before the New Architecture is enabled in your application. -## Use a React Native >= 0.68 release +## Use a React Native >= 0.68 Release React Native released the support for the New Architecture with the release `0.68.0`. -This guide is written with the expectation that you’re using the latest React Native release. At the moment of writing, this is `0.70.0`. Other than this guide, you can leverage the [upgrade helper](https://react-native-community.github.io/upgrade-helper/) to determine what other changes may be required for your project. +This guide is written with the expectation that you’re using the latest React Native release. At the moment of writing, this is `0.70.0`. Besides this guide, you can leverage the [upgrade helper](https://react-native-community.github.io/upgrade-helper/) to determine what other changes may be required for your project. To update to the most recent version of React Native, you can run this command: @@ -27,7 +27,7 @@ Starting from React Native `0.69.0`, you may also need to update the version of yarn add react@18.0.0 ``` -### Android specifics +### Android Specifics Using the New Architecture on Android has some prerequisites that you need to meet: @@ -139,9 +139,9 @@ task copyDownloadableDepsToLibs(type: Copy) { + } ``` -Finally, it’s time to update your project to use the `react-native` dependency from source, rather than using a precompiled artifact from the NPM package. This is needed as the later setup will rely on building the native code from source. +Finally, it’s time to update your project to use the `react-native` dependency from the source rather than using a precompiled artifact from the NPM package. This is needed as the later setup will rely on building the native code from the source. -Let’s edit your **module-level** `build.gradle` (the one inside `app/` folder) and change the following line: +Let’s edit your **module-level** `build.gradle` (the one inside the `app/` folder) and change the following line: ```diff dependencies { @@ -151,7 +151,7 @@ dependencies { ## Use Hermes -Hermes is an open-source JavaScript engine optimized for React Native. Hermes is enabled by default and you have to explicitly disable it if you want to use JSC. +Hermes is an open-source JavaScript engine optimized for React Native. Hermes is enabled by default, and you have to explicitly disable it if you want to use JSC. We highly recommend using Hermes in your application. With Hermes enabled, you will be able to use the JavaScript debugger in Flipper to directly debug your JavaScript code. @@ -159,7 +159,7 @@ Please [follow the instructions on the React Native website](hermes) to learn ho :::caution -**iOS:** If you opt out of using Hermes, you will need to replace `HermesExecutorFactory` with `JSCExecutorFactory` in any examples used throughout the rest of this guide. +**iOS:** If you opt-out of using Hermes, you will need to replace `HermesExecutorFactory` with `JSCExecutorFactory` in any examples used throughout the rest of this guide. ::: @@ -201,7 +201,7 @@ cd android ./gradlew clean ``` -## iOS: Make the project build +## iOS: Build the Project After upgrading the project, there are a few changes you need to apply: @@ -228,7 +228,7 @@ echo 'export NODE_BINARY=$(command -v node)' > .xcode.env ``` If you need it, you can also open the file and replace the `$(command -v node)` with the path to the node executable. -React Native supports also a local version of this file `.xcode.env.local`. This file is not synced with the repository to let you customize your local setup, if it differs from the Continuous Integration or the team one. +React Native also supports a local version of this file `.xcode.env.local`. This file is not synced with the repository to let you customize your local setup, if it differs from the Continuous Integration or the team one. ## iOS: Use Objective-C++ (`.mm` extension) @@ -261,7 +261,7 @@ Then, declare your app delegate as a `RCTCxxBridgeDelegate` provider: @end ``` -To conform to the `RCTCxxBridgeDelegate` protocol, you will need to implement the `jsExecutorFactoryForBridge:` method. Typically, this is where you would return a `JSCExecutorFactory` or `HermesExecutorFactory`, and we will use it to install our TurboModules bindings later on. +To conform to the `RCTCxxBridgeDelegate` protocol, you must implement the `jsExecutorFactoryForBridge:` method. Typically, this is where you would return a `JSCExecutorFactory` or `HermesExecutorFactory`, and we will use it to install our TurboModules bindings later on. You can implement the `jsExecutorFactoryForBridge:` method like this: diff --git a/docs/new-architecture-library-android.md b/docs/new-architecture-library-android.md index 09f1ee2fb7f..f0f702941fb 100644 --- a/docs/new-architecture-library-android.md +++ b/docs/new-architecture-library-android.md @@ -7,11 +7,11 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; -Once you have defined the JavaScript specs for your native modules as part of the [prerequisites](new-architecture-library-intro), setup the configuration of the Codegen, and followed the Android/Gradle setup, you are now ready to migrate your library to the new architecture. Here are the steps you can follow to accomplish this. +Once you have defined the JavaScript specs for your native modules as part of the [prerequisites](new-architecture-library-intro), set up the configuration of the Codegen, and follow the Android/Gradle setup, you are now ready to migrate your library to the new architecture. Here are the steps you can follow to accomplish this. -## 1. Extend or implement the code-generated native interfaces +## 1. Extend or Implement the Code-generated Native Interfaces -The JavaScript spec for your native module or component will be used to generate native interface code for each supported platform (i.e. Android and iOS). These native interface files will be generated **when a React Native application that depends on your library is built**. +The JavaScript spec for your native module or component will be used to generate native interface code for each supported platform (i.e., Android and iOS). These native interface files will be generated **when a React Native application that depends on your library is built**. While this generated native interface code **will not ship as part of your library**, you do need to make sure your Java/Kotlin code conforms to the protocols provided by these native interface files. @@ -23,7 +23,7 @@ You can invoke the `generateCodegenArtifactsFromSchema` Gradle task to generate The files that are output can be found inside `build/generated/source/codegen` and **should not be committed**, but you’ll need to refer to them to determine what changes you need to make to your native modules in order for them to provide an implementation for each generated interface. -The output of the codegen for a module called `NativeAwesomeManager` will look like this: +The output of the Codegen for a module called `NativeAwesomeManager` will look like this: ``` app/build/generated/source/codegen @@ -51,9 +51,9 @@ app/build/generated/source/codegen └── schema.json ``` -### Extends the abstract class provided by the codegen +### Extends the Abstract Class Provided by the Codegen -Update your native module or component to ensure it **extends the abstract class** that has been code-generated from your JavaScript specs (i.e. the `NativeAwesomeManagerSpec.java` file from the previous example). +Update your native module or component to ensure it **extends the abstract class** that has been code-generated from your JavaScript specs (i.e., the `NativeAwesomeManagerSpec.java` file from the previous example). Following the example set forth in the previous section, your library might import `NativeAwesomeManagerSpec`, implement the relevant native interface and the necessary methods for it: @@ -115,4 +115,4 @@ class NativeAwesomeManager(reactContext: ReactApplicationContext) : -Please note that the **generated abstract class** that you’re now extending (`MyAwesomeSpec` in this example), is itself extending `ReactContextBaseJavaModule`. Therefore you should not use access to any of the method/fields you were previously using (e.g. the `ReactApplicationContext` and so on). Moreover the generated class will now also implement the `TurboModule` interface for you. +Please note that the **generated abstract class** that you’re now extending (`MyAwesomeSpec` in this example) is itself extending `ReactContextBaseJavaModule`. Therefore you should not use access to any of the method/fields you were previously using (e.g., the `ReactApplicationContext` and so on). Moreover, the generated class will now also implement the `TurboModule` interface for you. diff --git a/docs/new-architecture-library-intro.md b/docs/new-architecture-library-intro.md index 403ce6f6343..9d688a8151e 100644 --- a/docs/new-architecture-library-intro.md +++ b/docs/new-architecture-library-intro.md @@ -14,14 +14,14 @@ The following steps will help ensure your modules and components are ready for t ## Define Specs in JavaScript -The JavaScript specs serve as the source of truth for the methods that are provided by each native module. They defines all APIs that are provided by the native module, along with the types of those constants and functions. -Using a **typed** spec file allows to be intentional and declare all the input arguments and outputs of your native module’s methods. +The JavaScript specs serve as the source of truth for the methods that are provided by each native module. They define all APIs that are provided by the native module, along with the types of those constants and functions. +Using a **typed** spec file allows you to be intentional and declare all the input arguments and outputs of your native module’s methods. :::info -Currently, this guide is written under the assumption that you will be using [Flow](https://flow.org/). The `react-native-codegen` package is also currently working only with Flow source as input. **TypeScript** support is in beta right now. +Currently, this guide is written under the assumption that you will be using [Flow](https://flow.org/). The `react-native-codegen` package is also currently working only with the Flow source as an input. **TypeScript** support is in beta right now. ::: -To adopt the New Architecture, you start by creating these specs for your native modules and native components. You can do this prior to actually migrating to the New Architecture: the specs will be used later on to generate native interface code for all the supported platforms, as a way to enforce uniform APIs across platforms. +To adopt the New Architecture, you start by creating these specs for your native modules and native components. You can do this prior to actually migrating to the New Architecture: the specs will be used later on to generate native interface code for all the supported platforms as a way to enforce uniform APIs across platforms. #### Turbomodules @@ -124,12 +124,12 @@ When using Flow or TypeScript, you will be using [type annotations](https://flow -In general, this means you can use primitive types (strings, numbers, booleans), as well as function types, object types, and array types. Union types, on the other hand, are not supported. All types must be read-only. For Flow: either `+` or `$ReadOnly<>` or `{||}` objects. For TypeScript: `readonly` for properties, `Readonly<>` for objects, and `ReadonlyArray<>` for arrays. +In general, this means you can use primitive types (strings, numbers, booleans), and function types, object types, and array types. Union types, on the other hand, are not supported. All types must be read-only. For Flow: either `+` or `$ReadOnly<>` or `{||}` objects. For TypeScript: `readonly` for properties, `Readonly<>` for objects, and `ReadonlyArray<>` for arrays. > See Appendix [I. Flow Type to Native Type Mapping](#i-flow-type-to-native-type-mapping). > See Appendix [II. TypeScript to Native Type Mapping](#ii-typescript-to-native-type-mapping). -### Codegen helper types +### Codegen Helper Types You can use predefined types for your JavaScript spec, here is a list of them: @@ -144,11 +144,11 @@ Later on those types are compiled to coresponding equivalents on target platform ### Be Consistent Across Platforms and Eliminate Type Ambiguity -Before adopting the New Architecture in your native module, you will need to ensure your methods are consistent across platforms. This is something you will realize as you set out to write the JavaScript spec for your native module - remember, that JavaScript spec defines what the methods will look like on all supported platforms. +Before adopting the New Architecture in your native module, you will need to ensure your methods are consistent across platforms. This is something you will realize as you set out to write the JavaScript spec for your native module - remember that JavaScript spec defines what the methods will look like on all supported platforms. -If your existing native module has methods with the same name on multiple platforms, but with different numbers or types of arguments across platforms, you will need to find a way to make these consistent. If you have methods that can take two or more different types for the same argument, you will also need to find a way to resolve this type ambiguity as type unions are intentionally not supported. +If your existing native module has methods with the same name on multiple platforms but with different numbers or types of arguments across platforms, you will need to find a way to make these consistent. If you have methods that can take two or more different types for the same argument, you will also need to find a way to resolve this type of ambiguity as type unions are intentionally not supported. -## Make sure _autolinking_ is enabled +## Make Sure _autolinking_ is Enabled @@ -195,7 +195,7 @@ To determine if your library is set up for autolinking, check the CocoaPods outp ## Configure Codegen -[Codegen](the-new-architecture/pillars-codegen) is a tool that runs when you build an Android app or when you install the dependencies of an iOS app. It creates some scaffolding code that you won't have to create manually. +[Codegen](the-new-architecture/pillars-codegen) is a tool that runs when you build an Android app or install the dependencies of an iOS app. It creates some scaffolding code that you won't have to create manually. Codegen can be configured in the `package.json` file of your Library. Add the following JSON object at the end of it. @@ -213,16 +213,16 @@ Codegen can be configured in the `package.json` file of your Library. Add the fo ``` - The `codegenConfig` is the key used by the Codegen to verify that there is some code to generate. -- The `name` field, is the name of the library. -- The `type` field is used to identify the type of module we want to create. Our suggestions is to keep `all` to support libraries that contains both TurboModule and Fabric Components. +- The `name` field is the name of the library. +- The `type` field is used to identify the type of module we want to create. Our suggestion is to keep `all` to support libraries that contain both TurboModule and Fabric Components. - The `jsSrcsDir` is the directory where the codegen will start looking for JavaScript specs. - The `android.javaPackageName` is the name of the package where the generated code wil end up. Android also requires to have the [React Gradle Plugin properly configured](new-architecture-app-intro#android-specifics) in your app. -## Preparing your JavaScript codebase for the new React Native Renderer (Fabric) +## Preparing your JavaScript Codebase for the new React Native Renderer (Fabric) -The new renderer also known as Fabric doesn’t use the UIManager so direct calls to UIManager will need to be migrated. Historically, calls to UIManager had some pretty complicated patterns. Fortunately, we’ve created new APIs that are much cleaner. These new APIs are forwards compatible with Fabric so you can migrate your code today and they will work properly when you turn on Fabric! +The new renderer, also known as Fabric, doesn’t use the UIManager, so direct calls to UIManager will need to be migrated. Historically, calls to UIManager had some pretty complicated patterns. Fortunately, we’ve created new APIs that are much cleaner. These new APIs are forward compatible with Fabric, so you can migrate your code today, and the APIs will work properly when you turn on Fabric! Fabric will be providing new type safe JS APIs that are much more ergonomic than some of the patterns we've seen in product code today. These APIs require references to the underlying component, no longer using the result of `findNodeHandle`. `findNodeHandle` is used to search the tree for a native component given a class instance. This was breaking the React abstraction model. `findNodeHandle` is not compatible with React 18. Deprecation of `findNodeHandle` in React Native is similar to the [deprecation of `findDOMNode` in React DOM](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage). @@ -275,7 +275,7 @@ class ChildComponent extends React.Component { We can’t convert this call to `this._ref.measure` because `this._ref` is an instance to `ChildComponent`, which is not a HostComponent and thus does not have a `measure` function. -`ChildComponent` renders a `View`, which is a HostComponent, so we need to get a reference to `View` instead. There are typically two approaches to get what we need. If the component we need to get the ref from is a function component using `forwardRef` is probably the right choice. If it is a class component with other public methods, adding a public method for getting the ref is an option. Here are examples of those two forms: +`ChildComponent` renders a `View`, which is a HostComponent, so we need to get a reference to `View` instead. There are typically two approaches to get what we need. If the component we need to get the ref from is a function component, using `forwardRef` is probably the right choice. If it is a class component with other public methods, adding a public method for getting the ref is an option. Here are examples of those two forms: #### Using `forwardRef` @@ -412,11 +412,11 @@ const styles = StyleSheet.create({ }); ``` -In this example when the View is pressed there is a `setNativeProps` call to update the style and accessibility props of the component. To migrate this component it’s important to understand its current behavior using `setNativeProps`. +In this example, when the View is pressed, there is a `setNativeProps` call to update the style and accessibility props of the component. To migrate this component, it’s important to understand its current behavior using `setNativeProps`. #### Pre-Fabric, Component Props Persist -On first render, the component props are those declared in the render function. After the View is pressed `_onSubmit` calls `setNativeProps` with updated prop values. +On the first render, the component props are those declared in the render function. After the View is pressed `_onSubmit` calls `setNativeProps` with updated prop values. The resulting component can be represented as such: ```jsx @@ -471,10 +471,10 @@ const styles = StyleSheet.create({ }); ``` -- We are using the `hasSubmitted` flag to represent whether or not we want to apply `styles.submittedView`. If the style was dynamic then it makes sense to store the style object in state -- `accessibility` is now explicitly passed to the View component as a boolean. This differs from the prior implementation where `accessibility` wasn’t passed as a prop in initial render but in this case we know the non-specification of `accessibility` is handled in the same way as `accessibilty={false}` +- We are using the `hasSubmitted` flag to represent whether or not we want to apply `styles.submittedView`. If the style was dynamic, then it makes sense to store the style object in state +- `accessibility` is now explicitly passed to the View component as a boolean. This differs from the prior implementation where `accessibility` wasn’t passed as a prop in the initial render, but in this case, we know the non-specification of `accessibility` is handled in the same way as `accessibilty={false}` -Be wary of your assumptions as uncaught subtleties can introduce differences in behavior! It’s a good idea to have snapshot tests of your component as they will highlight any differences pre and post your migration. +Be wary of your assumptions, as uncaught subtleties can introduce differences in behavior! It’s a good idea to have snapshot tests of your component as they will highlight any differences pre and post your migration. ### Move the call to `requireNativeComponent` to a separate file @@ -540,7 +540,7 @@ export default require('./RNTMyNativeViewNativeComponent') ### Migrating off `dispatchViewManagerCommand` -Similar to one above, in an effort to avoid calling methods on the UIManager, all view manager methods are now called through an instance of `NativeCommands`. `codegenNativeCommands` is a new API to code-generate `NativeCommands` given an interface of your view manager’s commands. +Similar to the one above, in an effort to avoid calling methods on the UIManager, all view manager methods are now called through an instance of `NativeCommands`. `codegenNativeCommands` is a new API to code-generate `NativeCommands` given an interface of your view manager’s commands. **Before** @@ -586,7 +586,7 @@ Note: - The first argument in the `moveToRegion` command is a HostComponent ref of the native component - The arguments to the `moveToRegion` command are enumerated in the signature - The command definition is co-located with the native component. This is an encouraged pattern -- Ensure you have included your command name in `supportedCommands` array +- Ensure you have included your command name in the `supportedCommands` array #### Using Your Command @@ -614,9 +614,9 @@ class MyComponent extends React.Component { } ``` -#### Updating Native implementation +#### Updating Native Implementation -In the example the code-generated `Commands` will dispatch `moveToRegion` call to the native component’s view manager. In addition to writing the JS interface, you’ll need to update your native implementation signatures to match the dispatched method call. See the mapping for [Android argument types](https://facebook.github.io/react-native/docs/native-modules-android#argument-types) and[iOS argument types](https://facebook.github.io/react-native/docs/native-modules-ios#argument-types) for reference. +In the example, the code-generated `Commands` will dispatch `moveToRegion` call to the native component’s view manager. In addition to writing the JS interface, you’ll need to update your native implementation signatures to match the dispatched method call. See the mapping for [Android argument types](https://facebook.github.io/react-native/docs/native-modules-android#argument-types) and[iOS argument types](https://facebook.github.io/react-native/docs/native-modules-ios#argument-types) for reference. **iOS** diff --git a/docs/new-architecture-library-ios.md b/docs/new-architecture-library-ios.md index 67a78515da1..8eca9aa3184 100644 --- a/docs/new-architecture-library-ios.md +++ b/docs/new-architecture-library-ios.md @@ -8,7 +8,7 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; -You have defined the JavaScript specs for your native modules as part of the [prerequisites](new-architecture-library-intro) and you are now ready to migrate your library to the New Architecture. Here are the steps you can follow to accomplish this. +You have defined the JavaScript specs for your native modules as part of the [prerequisites](new-architecture-library-intro), and you are now ready to migrate your library to the New Architecture. Here are the steps you can follow to accomplish this. ## 1. Updating your Podspec for the New Architecture @@ -42,11 +42,11 @@ Pod::Spec.new do |s| end ``` -## 2. Extend or implement the code-generated native interfaces +## 2. Extend or Implement the Code-generated Native Interfaces -The JavaScript spec for your native module or component will be used to generate native interface code for each supported platform (i.e. Android and iOS). These native interface files will be generated when a React Native application that depends on your library is built. +The JavaScript spec for your native module or component will be used to generate native interface code for each supported platform (i.e., Android and iOS). These native interface files will be generated when a React Native application that depends on your library is built. -While this generated native interface code **will not ship as part of your library**, you do need to make sure your Objective-C or Java code conforms to the protocols provided by these native interface files. You can use the Codegen script to generate your library’s native interface code in order to use **as reference**. +While this generated native interface code **will not ship as part of your library**, you do need to make sure your Objective-C or Java code conforms to the protocols provided by these native interface files. You can use the Codegen script to generate your library’s native interface code in order to use it **as reference**. ```sh cd @@ -55,7 +55,7 @@ node node_modules/react-native/scripts/generate-artifacts.js \ --outputPath \ ``` -This command will generate the boilerplate code required by iOS in the output path provided as paramenter. +This command will generate the boilerplate code required by iOS in the output path provided as a parameter. The files that are output by the script **should not be committed**, but you’ll need to refer to them to determine what changes you need to make to your native modules in order for them to provide an implementation for each generated `@protocol` / native interface. @@ -83,4 +83,4 @@ RCT_EXPORT_METHOD(getString:(NSString *)string } ``` -For an existing native module, you will likely already have one or more instances of [`RCT_EXPORT_METHOD`](native-modules-ios#export-a-native-method-to-javascript). To migrate to the New Architecture, you’ll need to make sure the method signature makes use of the structs provided by the codegen output. +For an existing native module, you will likely already have one or more instances of [`RCT_EXPORT_METHOD`](native-modules-ios#export-a-native-method-to-javascript). To migrate to the New Architecture, you’ll need to make sure the method signature uses the structs provided by the Codegen output. diff --git a/docs/the-new-architecture/backward-compatibility-fabric-components.md b/docs/the-new-architecture/backward-compatibility-fabric-components.md index 8226a24730f..64f93c1834f 100644 --- a/docs/the-new-architecture/backward-compatibility-fabric-components.md +++ b/docs/the-new-architecture/backward-compatibility-fabric-components.md @@ -12,14 +12,14 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -The creation of a backward compatible Fabric Component requires the knowledge of how to create a Fabric Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). +Creating a backward compatible Fabric Component requires the knowledge of how to create a Fabric Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). -Fabric Components only work when the New Architecture is properly setup. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. +Fabric Components only work when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: -Creating a backward compatible Fabric Component lets your users continue leverage your library, independently from the architecture they use. The creation of such a component requires a few steps: +Creating a backward compatible Fabric Component lets your users continue to leverage your library independently from the architecture they use. The creation of such a component requires a few steps: -1. Configure the library so that dependencies are prepared set up properly for both the Old and the New Architecture. +1. Configure the library so that dependencies are prepared to set up properly for both the Old and the New Architecture. 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. @@ -31,7 +31,7 @@ While the last step is the same for all the platforms, the first two steps are d ### iOS -The Apple platform installs Fabric Components using [Cocoapods](https://cocoapods.org) as dependency manager. +The Apple platform installs Fabric Components using [Cocoapods](https://cocoapods.org) as a dependency manager. Every Fabric Component defines a `podspec` that looks like this: @@ -107,7 +107,7 @@ This `if` guard prevents the dependencies from being installed when the environm To create a module that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. :::note -Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure the maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. +Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: To configure the Fabric Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: @@ -136,11 +136,11 @@ defaultConfig { } ``` -This changes do three main things: +These changes do three main things: 1. The first lines define a function that returns whether the New Architecture is enabled or not. 2. The `buildConfigField` line defines a build configuration boolean field called `IS_NEW_ARCHITECTURE_ENABLED`, and initialize it using the function declared in the first step. This allows you to check at runtime if a user has specified the `newArchEnabled` property or not. -3. The last lines leverage the function declared in step one to decide which source sets we need to build, depending on the choosen architecture. +3. The last lines leverage the function declared in step one to decide which source sets we need to build, depending on the chosen architecture. ## Update the codebase @@ -387,7 +387,7 @@ For a Fabric Component, the source of truth is the `NativeComponent. import MyComponent from 'your-component/src/index'; ``` -The **goal** is to conditionally `export` from the `index` file the proper object, given the architecture chosen by the user. We can achieve this with a code that looks like this: +The **goal** is to conditionally `export` the proper object from the `index` file , given the architecture chosen by the user. We can achieve this with a code that looks like this: NativeComponent` spec to access the Fabric Component. +- If that object is `null`, then the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). +- If that object is set, the app is running with Fabric enabled, and it should use the `NativeComponent` spec to access the Fabric Component. diff --git a/docs/the-new-architecture/backward-compatibility-turbomodules.md b/docs/the-new-architecture/backward-compatibility-turbomodules.md index 42d8a1cbc87..9b636d4fb79 100644 --- a/docs/the-new-architecture/backward-compatibility-turbomodules.md +++ b/docs/the-new-architecture/backward-compatibility-turbomodules.md @@ -12,12 +12,12 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -The creation of a backward compatible TurboModule requires the knowledge of how to create a TurboModule. To recall these concepts, have a look at this [guide](pillars-turbomodules). +Creating a backward compatible TurboModule requires the knowledge of how to create a TurboModule. To recall these concepts, have a look at this [guide](pillars-turbomodules). -TurboModules only works when the New Architecture is properly setup. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. +TurboModules only works when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: -Creating a backward compatible TurboModule lets your users continue leverage your library, independently from the architecture they use. The creation of such a module requires a few steps: +Creating a backward compatible TurboModule lets your users continue to leverage your library, independently from the architecture they use. The creation of such a module requires a few steps: 1. Configure the library so that dependencies are prepared set up properly for both the Old and the New Architecture. 1. Update the codebase so that the New Architecture types are not compiled when not available. @@ -31,7 +31,7 @@ While the last step is the same for all the platforms, the first two steps are d ### iOS -The Apple platform installs TurboModules using [Cocoapods](https://cocoapods.org) as dependency manager. +The Apple platform installs TurboModules using [Cocoapods](https://cocoapods.org) as a dependency manager. Every TurboModule defines a `podspec` that looks like this: @@ -87,7 +87,7 @@ pod install RCT_NEW_ARCH_ENABLED=1 pod install ``` -Therefore, we can leverage this environment variable in the `podspec` to exclude the settings and the dependencies that are related to the New Architecture: +Therefore, we can leverage this environment variable in the `podspec` to exclude the settings and the dependencies, that are related to the New Architecture: ```diff + if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then @@ -142,7 +142,7 @@ This changes do three main things: 1. The first lines define a function that returns whether the New Architecture is enabled or not. 2. The `buildConfigField` line defines a build configuration boolean field called `IS_NEW_ARCHITECTURE_ENABLED`, and initialize it using the function declared in the first step. This allows you to check at runtime if a user has specified the `newArchEnabled` property or not. -3. The last lines leverage the function declared in step one to decide which source sets we need to build, depending on the choosen architecture. +3. The last lines leverage the function declared in step one to decide which source sets we need to build, depending on the chosen architecture. ## Update the codebase @@ -150,7 +150,7 @@ This changes do three main things: The second step is to instruct Xcode to avoid compiling all the lines using the New Architecture types and files when we are building an app with the Old Architecture. -The file to change is the module implementation file, which is usually a `.mm` file. That file is structured as follow: +The file to change is the module implementation file, which is usually a `.mm` file. That file is structured as follows: - Some `#import` statements, among which there is a `.h` file. - The module implementation, using the various `RCT_EXPORT_xxx` and `RCT_REMAP_xxx` macros. @@ -222,7 +222,7 @@ my-module └── package.json ``` -The code that should go in the `MyModuleImpl.java` and that can be shared by the Native Module and the TurboModule is, for example: +The code that should go in the `MyModuleImpl.java`, and that can be shared by the Native Module and the TurboModule is, for example: ```java title="example of MyModuleImple.java" package com.MyModule; @@ -319,7 +319,7 @@ For a TurboModule, the source of truth is the `Native.js` (or `.ts`) s import MyModule from 'your-module/src/index'; ``` -The **goal** is to conditionally `export` from the `index` file the proper object, given the architecture chosen by the user. We can achieve this with a code that looks like this: +The **goal** is to conditionally `export` the proper object from the `index` file , given the architecture chosen by the user. We can achieve this with a code that looks like this: :::note -If you are using TypeScript and you want to follow the example, make sure to `export` the `NativeModule` in a separate `ts` file called `.ts`. +If you are using TypeScript and you want to follow the example, ensure to `export` the `NativeModule` in a separate `ts` file called `.ts`. ::: Whether you are using Flow or TypeScript for your specs, we understand which architecture is running by checking whether the `global.__turboModuleProxy` object has been set or not. :::caution -The `global.__turboModuleProxy` API may change in the future for a function that encapsulate this check. +The `global.__turboModuleProxy` API may change in the future for a function that encapsulates this check. ::: - If that object is `null`, the app has not enabled the TurboModule feature. It's running on the Old Architecture, and the fallback is to use the default [`NativeModule` implementation](../native-modules-intro). -- If that object is set, the app is running with the TurboModules enabled and it should use the `Native` spec to access the TurboModule. +- If that object is set, the app is running with the TurboModules enabled, and it should use the `Native` spec to access the TurboModule. diff --git a/docs/the-new-architecture/landing-page.md b/docs/the-new-architecture/landing-page.md index 403a1dee659..fd8abf53fcf 100644 --- a/docs/the-new-architecture/landing-page.md +++ b/docs/the-new-architecture/landing-page.md @@ -7,23 +7,23 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; -Starting from version 0.68, React Native provides the New Architecture, which offers developers new capabilities for building highly performant and responsive apps. Visit [Why a New Architecture](why) to learn more about what drove the decision to re-architect, and the benefits it provides. +Starting from version 0.68, React Native provides the New Architecture, which offers developers new capabilities for building highly performant and responsive apps. Visit [Why a New Architecture](why) to learn more about what drove the decision to re-architect and the benefits it provides. -In order to achieve these benefits, we had to rethink how Native Modules and Native Components work. This led us to develop the [Pillars of the New Architecture](pillars): +To achieve these benefits, we had to rethink how Native Modules and Native Components work. This led us to develop the [Pillars of the New Architecture](pillars): - [TurboModules](pillars-turbomodules), a framework to support efficient and flexible integration with native code - [Fabric renderer and components](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering -- [Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture, via static typing in JavaScript +- [Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture via static typing in JavaScript -## Get started with the New Architecture +## Get Started with the New Architecture -### For app developers +### For App Developers To **create a new app** using the New Architecture, head over to [Creating a New Architecture App](use-app-template), which will get you up and running in a few quick steps with the new app template. To **migrate an existing app** to the New Architecture, follow [Adopting the New Architecture](../new-architecture-intro). -### For library maintainers +### For Library Maintainers First, read up on the core concepts outlined in the [Pillars](pillars) section. diff --git a/docs/the-new-architecture/pillars-codegen.md b/docs/the-new-architecture/pillars-codegen.md index 11bd5062190..d736c340546 100644 --- a/docs/the-new-architecture/pillars-codegen.md +++ b/docs/the-new-architecture/pillars-codegen.md @@ -9,17 +9,17 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; -The **Codegen** is not a proper pillar, but it is a tool that can be used to avoid writing of a lot of repetitive code. Using the **Codegen** is not mandatory: all the code that is generated by it can also be written manually. However, it generates scaffolding code that could save you a lot of time. +The **Codegen** is not a proper pillar, but it is a tool that can be used to avoid writing a lot of repetitive code. Using **Codegen** is not mandatory: all the code that is generated by it can also be written manually. However, it generates scaffolding code that could save you a lot of time. -The **Codegen** is invoked automatically by React Native every time an iOS or an Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**TurboModules**](./pillars-turbomodules) and [**Fabric Components**](./pillars-fabric-components), for example. +The **Codegen** is invoked automatically by React Native every time an iOS or Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**TurboModules**](./pillars-turbomodules) and [**Fabric Components**](./pillars-fabric-components), for example. -This guide teaches how to configure the **Codegen**, how to invoke it manually for each platform, and it describes the generated code. +This guide teaches how to configure the **Codegen**, and how to invoke it manually for each platform, and describes the generated code. # Prerequisites You always need a React Native app to generate the code properly, even when invoking the **Codegen** manually. -The **Codegen** process is tightly coupled with the build of the app and the scripts are located in the `react-native` NPM package. +The **Codegen** process is tightly coupled with the build of the app, and the scripts are located in the `react-native` NPM package. For the sake of this guide, create a project using the React Native CLI as follows: @@ -48,9 +48,9 @@ The rest of this guide assumes that you have a `TurboModule` and/or a `Fabric Co The **Codegen** for iOS relies on some Node scripts that are invoked during the build process. The scripts are located in the `MyApp/node_modules/react_native/scripts/` folder. -The script that you have to run is the `generate-artifacts.js` script. This searches among all the dependencies of the app, looking for JS files which respects some specific conventions (look at [TurboModules](pillars-turbomodules) and [Fabric Components](pillars-fabric-components) sections for details) and it generates the required code. +The script that you have to run is the `generate-artifacts.js` script. This searches among all the dependencies of the app, looking for JS files that respects some specific conventions (look at [TurboModules](pillars-turbomodules) and [Fabric Components](pillars-fabric-components) sections for details), and it generates the required code. -To invoke the script you can run this command from the root folder of your app: +To invoke the script, you can run this command from the root folder of your app: ```sh node node_modules/react_native/scripts/generate-artifacts.js \ @@ -58,7 +58,7 @@ node node_modules/react_native/scripts/generate-artifacts.js \ --outputPath \ ``` -Given that the app has `TurboModules` and/or `Fabric Components` configured as a dependency, the **Codegen** will look for all of them and it will generate the code in the path you provided. +Given that the app has `TurboModules` and/or `Fabric Components` configured as a dependency, **Codegen** looks for all of them and generates the code in the path you provided. ## The Generated Code @@ -100,9 +100,9 @@ codegen └── ShadowNodes.h ``` -The `codegen` folder sits at the root of the hierarchy, as expected. Nested into it there are two more folders: `build/generated`. +The `codegen` folder sits at the root of the hierarchy, as expected. Nested into it, there are two more folders: `build/generated`. -Then, there is an `ios` folder which contains: +Then, there is an `ios` folder that contains: - A custom folder for each TurboModule. - The header (`.h`) and implementation (`.mm`) files for the `RCTThirdPartyFabricComponentsProvider`. @@ -114,13 +114,13 @@ In the example above, there are both a TurboModule and a set of Fabric Component Each TurboModule's folder contains two files: an interface file and an implementation file. -The interface files have the same name of the TurboModule and they contain methods to initialize the JSI interface. +The interface files have the same name as that of the TurboModule and contain methods to initialize the JSI interface. -The implementation files, instead, have the `-generated` suffix and they contains the logic to invoke the native methods from JS and viceversa. +The implementation files, instead, have the `-generated` suffix and contain the logic to invoke the native methods from JS and vice-versa. ### Fabric Components -The content of each Fabric Component folder contains several files. The basic element for a Fabric Componenent is the `ShadowNode`: it represents a node in the React absract tree. The `ShadowNode` represents a React entity, therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. +The content of each Fabric Component folder contains several files. The basic element for a Fabric Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore, it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. @@ -128,13 +128,13 @@ For further details about how Fabric works, have a look at the [Renderer](/archi ### RCTThirdPartyFabricComponentsProvider -These are an interface and an implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Component. Once React Native has an handle to that class, it can instantiate it. +These are interface and implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Component. Once React Native has a handle to that class, it can instantiate it. # Android ## Running the Codegen -Android `Codegen` relies on a Gradle task to generate the required code. First, you need to configure the Android app to work with the New Architecture, otherwise the Gradle task fails. +Android `Codegen` relies on a Gradle task to generate the required code. First, you need to configure the Android app to work with the New Architecture; otherwise, the Gradle task fails. 1. Open the `MyApp/android/gradle.properties` file. 1. Flip the `newArchEnabled` flag from `false` to `true`. @@ -145,7 +145,7 @@ After that, you can navigate into the `SampleApp/android` folder and run: ./gradlew generateCodegenArtifactsFromSchema ``` -This tasks invokes the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. +These tasks invoke the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. ## The Generated Code @@ -213,20 +213,20 @@ codegen -Java can't interoperate seamlessly with C++ as Objective-C++ does. To work properly, the **Codegen** creates some bridging between the Java and the C++ world in the `jni` folder, where the Java Native Interfaces are defined. +Java can't interoperate seamlessly with C++ as Objective-C++ does. To work properly, **Codegen** creates some bridging between the Java and the C++ world in the `jni` folder, where the Java Native Interfaces are defined. -Notice that both TurboModules and Fabric Components comes with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. +Notice that both TurboModules and Fabric Components come with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. ### TurboModule -The **Codegen** generates a Java abstract class in the `java` package with the same name of the TurboModule. This abstract class has to be implemented by the JNI C++ implementation. +The **Codegen** generates a Java abstract class in the `java` package with the same name as that of the TurboModule. This abstract class has to be implemented by the JNI C++ implementation. -Then, it generates the C++ files in the `jni` folder. They follow the same iOS convention: there is an interface called `MyTurbomodule.h` and an implementation file called `MyTurbomodule-generated.cpp`. The former is an interface that allows React Natvie to initialize the JSI interface for the TurboModule. The latter is the implementation file which contains the logic to invoke the native method from JS and viceversa. +Then, it generates the C++ files in the `jni` folder. They follow the same iOS convention: there is an interface called `MyTurbomodule.h` and an implementation file called `MyTurbomodule-generated.cpp`. The former is an interface that allows React Native to initialize the JSI interface for the TurboModule. The latter is the implementation file which contains the logic to invoke the native method from JS and vice-versa. ### Fabric Component The **Codegen** for a Fabric Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Component](./pillars-fabric-components) for details). -Then, there is a layer of JNI C++ files that are used by Fabric to render the components. The basic element for a Fabric Componenent is the `ShadowNode`: it represents a node in the React absract tree. The `ShadowNode` represents a React entity, therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. +Then, there is a layer of JNI C++ files that are used by Fabric to render the components. The basic element for a Fabric Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. -The **Codegen** also creates a `ComponentDescriptor.h` which is required to get a proper handle to the Fabric Component. +The **Codegen** also creates a `ComponentDescriptor.h`, which is required to get a proper handle on the Fabric Component. diff --git a/docs/the-new-architecture/pillars-fabric-components.md b/docs/the-new-architecture/pillars-fabric-components.md index a4271e49985..fa9fd98321c 100644 --- a/docs/the-new-architecture/pillars-fabric-components.md +++ b/docs/the-new-architecture/pillars-fabric-components.md @@ -12,7 +12,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con A Fabric Component is a UI component rendered on the screen using the [Fabric Renderer](https://reactnative.dev/architecture/fabric-renderer). Using Fabric Components instead of Native Components allows us to reap all the [benefits](./why) of the **New Architecture**: - Strongly typed interfaces that are consistent across platforms. -- The ability to write your code in C++, either exclusively or integrated with another native platform language, reducing the need to duplicate implementations across platforms. +- The ability to write your code in C++, either exclusively or integrated with another native platform language, hence reducing the need to duplicate implementations across platforms. - The use of JSI, a JavaScript interface for native code, which allows for more efficient communication between native and JavaScript code than the bridge. A Fabric Component is created starting from a **JavaScript specification**. Then [**Codegen**](./pillars-codegen) creates some C++ scaffolding code to connect the component-specific logic (for example, accessing some native platform capability) to the rest of the React Native infrastructure. The C++ code is the same for all the platforms. Once the component is properly connected with the scaffolding code, it is ready to be imported and used by an app. @@ -32,17 +32,17 @@ To create a Fabric Component, you have to follow these steps: 2. Configure the component so that **Codegen** can create the shared code and it can be added as a dependency for an app. 3. Write the required native code. -Once these steps are done, the component is ready to be consumed by an app. The guide shows how to add it to an app, leveraging _autolinking_, and how to reference it from the JavaScript code. +Once these steps are done, the component is ready to be consumed by an app. The guide shows how to add it to an app by leveraging _autolinking_, and how to reference it from the JavaScript code. ## 1. Folder Setup -In order to keep the component decoupled from the app, it's a good idea to define the module separately from the app, and then add it as a dependency to your app later. This is also what you'll do for writing Fabric Component that can be released as open-source libraries later. +In order to keep the component decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Fabric Component that can be released as open-source libraries later. For this guide, you are going to create a Fabric Component that centers some text on the screen. Create a new folder at the same level of the app and call it `RTNCenteredText`. -In this folder, create three subfolders: `js`, `ios` and `android`. +In this folder, create three subfolders: `js`, `ios`, and `android`. The final result should look like this: @@ -108,7 +108,7 @@ export default codegenNativeComponent( -At the beginning of the spec files, there are the imports. The most important imports, required by every Fabric Component, are: +At the beginning of the spec files, there are the imports. The most important imports, required by every Fabric Component are: - The `HostComponent`: type the exported component needs to conform to. - The `codegenNativeComponent` function: responsible to actually register the component in the JavaScript runtime. @@ -226,9 +226,9 @@ Pod::Spec.new do |s| end ``` -The `.podspec` file has to be a sibling of the `package.json` file and its name is the one we set in the `package.json`'s `name` property: `rtn-centered-text`. +The `.podspec` file has to be a sibling of the `package.json` file, and its name is the one we set in the `package.json`'s `name` property: `rtn-centered-text`. -The first part of the file prepares some variables we will use throughout the rest of it. Then, there is a section that contains some information used to configure the pod, like its name, version, and description. Finally, we have a set of dependencies that are required by the New Architecture. +The first part of the file prepares some variables we will use throughout the rest of it. Then, there is a section that contains some information used to configure the pod, like its name, version, and description. Finally, we have a set of dependencies that the New Architecture requires. ### Android: `build.gradle`, `AndroidManifest.xml`, a `ReactPackage` class @@ -350,9 +350,9 @@ The last step requires you to write some native code to connect the JavaScript s 1. Run **Codegen** to see what would be generated. 2. Write the native code that will make it work. -When developing a React Native app that uses a Fabric Component, it is responsibility of the app to actually generate the code using **Codegen**. However, when developing a Fabric Component as a library, it needs to reference the generated code and it is useful to see what the app will generate. +When developing a React Native app that uses a Fabric Component, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a Fabric Component as a library, it needs to reference the generated code, and it is useful to see what the app will generate. -As first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](./pillars-codegen.md) +As the first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](./pillars-codegen.md). :::caution The code generated by **Codegen** in this step should not be committed to the versioning system. React Native apps are able to generate the code when the app is built. This allows an app to ensure that all libraries have code generated for the correct version of React Native. @@ -456,14 +456,14 @@ RCT_EXPORT_VIEW_PROPERTY(text, NSString) @end ``` -This file is the manager for the Fabric Component. The manager objects are used by the React Native runtime to register the modules, the properties and the methods so that they are available to the JavaScript side. +This file is the manager for the Fabric Component. React Native runtime uses manager objects to register the modules, properties and methods to make them available to the JavaScript side. -The most important call is to the `RCT_EXPORT_MODULE` which is required to export the module so that Fabric can retrieve and instantiate it. +The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that Fabric can retrieve and instantiate it. Then, you have to expose the `text` property for the Fabric Component. This is done with the `RCT_EXPORT_VIEW_PROPERTY` macro, specifying a name and a type. :::info -There are other macros that can be used to export custom properties, emitters and other constructs. You can view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Views/RCTViewManager.h) +There are other macros that can be used to export custom properties, emitters, and other constructs. You can view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Views/RCTViewManager.h). ::: ##### RTNCenteredText.h @@ -561,17 +561,17 @@ Class RTNCenteredTextCls(void) This file contains the actual implementation of the view. -It starts with some imports which require you to read the files generated by **Codegen**. +It starts with some imports, which require you to read the files generated by **Codegen**. -The component has to conform to a specific protocol generated by **Codegen**, in this case `RCTRTNCenteredTextViewProtocol`. +The component has to conform to a specific protocol generated by **Codegen**, in this case, `RCTRTNCenteredTextViewProtocol`. -Then, the file defines a static `(ComponentDescriptorProvider)componentDescriptorProvider` method which is used by Fabric to retrieve the descriptor provider to instantiate the object. +Then, the file defines a static `(ComponentDescriptorProvider)componentDescriptorProvider` method which Fabric uses to retrieve the descriptor provider to instantiate the object. -Then, there is the constructor of the view: the `init` method. In this method, it is important to create a `defaultProps` struct using the `RTNCenteredTextProps` type from **Codegen**. You need to assign it to the private `_props` property to correctly initialize the Fabric Component. The remaining part of the initializer is standard Objective-C code to create views and layout them with AutoLayout. +Then, there is the constructor of the view: the `init` method. In this method, it is important to create a `defaultProps` struct using the `RTNCenteredTextProps` type from **Codegen**. You need to assign it to the private `_props` to initialize the Fabric Component correctly. The remaining part of the initializer is standard Objective-C code to create views and layout them with AutoLayout. The last two pieces are the `updateProps` method and the `RTNCenteredTextCls` method. -The `updateProps` method is invoked by Fabric every time a prop changes in JavaScript. The props passed as parameters are downcasted to the proper `RTNCenteredTextProps` type and then they are used to update the native code if needed. Notice that the superclass method `[super updateProps]` must be invoked as the last statement of this method, otherwise the `props` and `oldProps` struct will have the same values and you'll not be able to use them to make decisions and to update the component. +The `updateProps` method is invoked by Fabric every time a prop changes in JavaScript. The props passed as parameters are downcasted to the proper `RTNCenteredTextProps` type, and then they are used to update the native code if needed. Notice that the superclass method `[super updateProps]` must be invoked as the last statement of this method; otherwise the `props` and `oldProps` struct will have the same values, and you'll not be able to use them to make decisions and to update the component. Finally, the `RTNCenteredTextCls` is another static method used to retrieve the correct instance of the class at runtime. diff --git a/docs/the-new-architecture/pillars-turbomodule.md b/docs/the-new-architecture/pillars-turbomodule.md index 77159a4fc24..b5afb3952ed 100644 --- a/docs/the-new-architecture/pillars-turbomodule.md +++ b/docs/the-new-architecture/pillars-turbomodule.md @@ -15,7 +15,7 @@ TurboModules are the next iteration on Native Modules that provide a few extra [ - Strongly typed interfaces that are consistent across platforms - The ability to write your code in C++, either exclusively or integrated with another native platform language, reducing the need to duplicate implementations across platforms - Lazy loading of modules, allowing for faster app startup -- The use of JSI, a JavaScript interface for native code, which allows for more efficient communication between native and JavaScript code than the bridge +- The use of JSI, a JavaScript interface for native code, allows for more efficient communication between native and JavaScript code than the bridge This guide will show you how to create a basic TurboModule. @@ -34,7 +34,7 @@ To create a TurboModule, we need to: ## 1. Folder Setup -In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app, and then add it as a dependency to your app later. This is also what you'll do for writing TurboModules that can be released as open-source libraries later. +In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing TurboModules that can be released as open-source libraries later. Next to your application, create a folder called `RTNCalculator`. **RTN** stands for "**R**eac**t** **N**ative", and is a recommended prefix for React Native modules. @@ -100,7 +100,7 @@ At the beginning of the spec files are the imports: - The `TurboModule` type, which defines the base interface for all TurboModules - The `TurboModuleRegistry` JavaScript module, which contains functions for loading TurboModules -The second section of the file contains the interface specification for the TurboModule. In this case, the interface defines the `add` function which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a TurboModule. +The second section of the file contains the interface specification for the TurboModule. In this case, the interface defines the `add` function, which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a TurboModule. Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the TurboModule if it's available. @@ -112,11 +112,11 @@ We are writing JavaScript files importing types from libraries, without setting Next, you need to add some configuration for [**Codegen**](pillars-codegen.md) and auto-linking. -Some of these configuration files are shared between iOS and Android, while the others are platform-specific. +Some configuration files are shared between iOS and Android, while the others are platform-specific. ### Shared -The shared configuration is a `package.json` file that will be used by yarn when installing your module. Create the `package.json` file in the root of the `RTNCalculator` directory. +The shared configuration is a `package.json` file used by yarn when installing your module. Create the `package.json` file in the root of the `RTNCalculator` directory. ```json title="package.json" { @@ -160,20 +160,20 @@ The shared configuration is a `package.json` file that will be used by yarn when } ``` -The upper part of the file contains some descriptive information like the name of the component, its version and its source files. Make sure to update the various placeholders which are wrapped in `<>`: replace all the occurrences of the ``, ``, and `` tokens. +The upper part of the file contains some descriptive information like the name of the component, its version, and its source files. Make sure to update the various placeholders which are wrapped in `<>`: replace all the occurrences of the ``, ``, and `` tokens. Then there are the dependencies for this package. For this guide, you need `react` and `react-native`. Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a TurboModule, thus the value to use is `modules`. +- `type`: The type of module contained by this package. In this case, it is a TurboModule; thus, the value to use is `modules`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. - `android.javaPackageName`: the package to use in the Java files generated by **Codegen**. ### iOS: Create the `podspec` file -For iOS, you'll need to create a `rtn-calculator.podspec` file which will define the module as a dependency for your app. It will stay in the root of `RTNCalculator`, alongside the `ios` folder. +For iOS, you'll need to create a `rtn-calculator.podspec` file, which will define the module as a dependency for your app. It will stay in the root of `RTNCalculator`, alongside the `ios` folder. The file will look like this: @@ -215,7 +215,7 @@ Pod::Spec.new do |s| end ``` -The `.podspec` file has to be a sibling of the `package.json` file and its name is the one we set in the `package.json`'s `name` property: `rtn-calculator`. +The `.podspec` file has to be a sibling of the `package.json` file, and its name is the one we set in the `package.json`'s `name` property: `rtn-calculator`. The first part of the file prepares some variables we will use throughout the rest of it. Then, there is a section that contains some information used to configure the pod, like its name, version, and description. Finally, we have a set of dependencies that are required by the New Architecture. @@ -225,7 +225,7 @@ To prepare Android to run **Codegen** you have to create three files: 1. The `build.gradle` with the **Codegen** configuration 1. The `AndroidManifest.xml` file -1. A java class that implements the `ReactPackage` interface. +1. A java class that implements the `ReactPackage` interface At the end of these steps, the `android` folder should look like this: @@ -325,7 +325,7 @@ public class CalculatorPackage extends TurboReactPackage { } ``` -The `ReactPackage` interface is used by React Native to understand what native classes the app has to use for the `ViewManager` and `Native Modules` exported by the library. +React Native uses the `ReactPackage` interface to understand what native classes the app has to use for the `ViewManager` and `Native Modules` exported by the library. ## 4. Native Code @@ -334,9 +334,9 @@ For the final step in getting your TurboModule ready to go, you'll need to write - Run **Codegen** to see what it generates. - Write your native code, implementing the generated interfaces. -When developing a React Native app that uses a TurboModule, it is responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore useful to see what the app will generate. +When developing a React Native app that uses a TurboModule, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore, useful to see what the app will generate. -As first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](pillars-codegen.md) +As the first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](pillars-codegen.md). :::caution The code generated by **Codegen** in this step should not be committed to the versioning system. React Native apps are able to generate the code when the app is built. This allows an app to ensure that all libraries have code generated for the correct version of React Native. @@ -395,7 +395,7 @@ The relevant path for the TurboModule interface is `generated/build/generated/io See the [Codegen](./pillars-codegen) section for further details on the generated files. :::note -When generating the scaffolding code using **Codegen**, iOS does not clean the `build` folder automatically. If you changed a the Spec name, for example, and then run **Codegen** again, the old files will be retained. +When generating the scaffolding code using **Codegen**, iOS does not clean the `build` folder automatically. If you changed the Spec name, for example, and then run **Codegen** again, the old files would be retained. If that happens, remember to remove the `build` folder before running the **Codegen** again. ``` @@ -472,7 +472,7 @@ Android follows similar steps to iOS. We have to generate the code for Android, #### Generate the Code - Android -To generate the code for Android, we need to manually invoke Codegen. This is done similarly to what we did for iOS: first, we need to add the package to the app and then we need to invoke a script. +To generate the code for Android, we need to manually invoke Codegen. This is done similarly to what we did for iOS: first, we need to add the package to the app, and then we need to invoke a script. ```sh title="Running Codegen for Android" cd MyApp diff --git a/docs/the-new-architecture/pillars.md b/docs/the-new-architecture/pillars.md index fdcfd555ac9..05a828af51c 100644 --- a/docs/the-new-architecture/pillars.md +++ b/docs/the-new-architecture/pillars.md @@ -7,16 +7,16 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; -The New Architecture is composed mainly by two pillars: +The New Architecture is composed mainly of two pillars: - [TurboModules](pillars-turbomodules) - [Fabric Components](pillars-fabric-components). -TurboModules are the preferred way to create libraries that leverage some platform specific API. Fabric Components are the preferred way to create reusable UI components, providing a native experience to the users. +TurboModules are the preferred way to create libraries that leverage some platform-specific API. Fabric Components are the preferred way to create reusable UI components, providing a native experience to the users. The main goal of this section is to drive the reader through a step-by-step guide to create their first TurboModule or Fabric Component. -The next sections contain an high-level overview of the pillars, together with the steps to create them. To create one of these pillars, the steps are: +The next sections contain a high-level overview of the pillars and the steps to create them. To create one of these pillars, the steps are: 1. Define a JavaScript specification using Flow or TypeScript. 1. Configure the dependencies management system to generate code from the provided spec. @@ -26,7 +26,7 @@ The next sections contain an high-level overview of the pillars, together with t Finally, we dive a little deeper into the [Codegen](pillars-codegen) process that is required to create all the C++ types and files used by our components, including some useful steps to work comfortably while developing the component. :::caution -To integrate a TurboModule or a Fabric Component in an app, the app has to run with the New Architecture enabled. +The app has to run with the **New Architecture enabled to integrate a TurboModule or a Fabric Component** in an app. To create a new app adopting the New Architecture, refer to the [Using the App Template](use-app-template) section. To migrate an existing app to the New Architecture, refer to the [Migration](../new-architecture-intro) guide. diff --git a/docs/the-new-architecture/use-app-template.md b/docs/the-new-architecture/use-app-template.md index ca4ed3d3dad..50b82a1b20f 100644 --- a/docs/the-new-architecture/use-app-template.md +++ b/docs/the-new-architecture/use-app-template.md @@ -11,17 +11,17 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; This page will help you create a new React Native app that uses the New Architecture. -## Development environment +## Development Environment -Before continuing, make sure you've followed all the steps in [Setting up the development environment](getting-started.md), under the **React Native CLI Quickstart** tab. +Before continuing, make sure you've followed all the steps in the[Setting up the development environment](getting-started.md) section under the **React Native CLI Quickstart** tab. If following the setup guide, stop when you reach the section **Running your React Native Application**, and resume following this guide. :::caution -If you're using Expo, you can't enable the New Architecture at the moment, and will have to wait for a future release of the Expo SDK. +If you're using Expo, you can't enable the New Architecture at the moment and will have to wait for a future release of the Expo SDK. ::: -## Creating a new application +## Creating a New Application @@ -43,7 +43,7 @@ Follow the steps below to enable the New Architecture and build the app. Hermes is an open-source JavaScript engine optimized for React Native. [Hermes will be the default engine in the future](https://github.com/reactwg/react-native-new-architecture/discussions/4), and we highly recommend you use it. -Please [follow the instructions on the React Native website](hermes.md) in order to enable Hermes in your application. +Please [follow the instructions on the React Native website](hermes.md) to enable Hermes in your application. ### Enable the New Architecture @@ -103,21 +103,21 @@ yarn android ``` :::note -You may notice longer build times with the New Architecture, due to additional step of C++ compilation with the Android NDK. To improve your build time, see [Speeding Up Your Build Phase](build-speed.md). +You may notice longer build times with the New Architecture due to additional step of C++ compilation with the Android NDK. To improve your build time, see [Speeding Up Your Build Phase](build-speed.md). ::: -### Confirming the New Architecture is in use +### Confirming the New Architecture is in Use -After you build and run the app, when Metro serves the JavaScript bundle, you should see `"fabric": true` in the Metro logs: +After you build and run the app when Metro serves the JavaScript bundle, you should see `"fabric": true` in the Metro logs: Metro shows fabric: true -### Want to know more? +### Want to Know More? -If you'd like to view the code changes relevant for the New Architecture, take a look at the [upgrade helper from version 0.67.4 to 0.68.0](https://react-native-community.github.io/upgrade-helper/?from=0.67.4&to=0.68.0). Files that were added for the New Architecture are marked with a yellow banner. +If you'd like to view the code changes relevant to the New Architecture, take a look at the [upgrade helper from version 0.67.4 to 0.68.0](https://react-native-community.github.io/upgrade-helper/?from=0.67.4&to=0.68.0). Files that were added for the New Architecture are marked with a yellow banner. For further explanations of what each file is doing, check out these guides to walk through the changes step-by-step: diff --git a/docs/the-new-architecture/why.md b/docs/the-new-architecture/why.md index 47bb4e7dd8e..84b8fe62e0e 100644 --- a/docs/the-new-architecture/why.md +++ b/docs/the-new-architecture/why.md @@ -1,44 +1,44 @@ --- id: why -title: Why A New Architecture +title: Why a New Architecture --- import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; -The goal of the New Architecture is to solve some of the issues that afflicted the Old Architecture in terms of performance and flexibility. This section provides the basic context to understand the Old Architecture limitations and how it has been possible to overcome them with the New Architecture. +The goal of the New Architecture is to solve some of the issues that afflicted the Old Architecture in terms of performance and flexibility. This section provides the basic context to understand the Old Architecture's limitations and how it has been possible to overcome them with the New Architecture. This is not a technical deep dive: for further technical information, refer to the [Architecture](/architecture/overview) tab of the website. ## Old Architecture's Issues -The Old Architecture used to work by serializing all the data that has to be passed from the JS layer to the native layer using a component called _The Bridge_. _The Bridge_ can be imagined as a bus where the producer layer sent some data for the consumer layer. The consumer could read the data, deserialize it and execute the required operations. +The Old Architecture used to work by serializing all the data that had to be passed from the JS layer to the native layer using a component called _The Bridge_. _The Bridge_ can be imagined as a bus where the producer layer sends some data for the consumer layer. The consumer could read the data, deserialize it and execute the required operations. _The Bridge_ had some intrinsic limitations: - **It was asynchronous:** one layer submitted the data to the bridge and asynchronously "waited" for the other layer to process them, even when this was not really necessary. -- **It was single threaded:** JS used to work on a single thread, therefore the computation that happened in that world had to be performed on that single thread. -- **It imposed extra overheads:** everytime one layer had to use the other one, it had to serialize some data. The other layer had to deserialize them. The chosen format was JSON, for its simplicity and human-readability, but despite being lightweight, it was a cost to pay. +- **It was single-threaded:** JS used to work on a single thread; therefore, the computation that happened in that world had to be performed on that single thread. +- **It imposed extra overheads:** every time one layer had to use the other one, it had to serialize some data. The other layer had to deserialize them. The chosen format was JSON for its simplicity and human-readability, but despite being lightweight, it was a cost to pay. ## New Architecture's Improvements -The New Architecture dropped the concept of _The Bridge_ in favor of another communication mechanism: the _JavaScript Interface (JSI)_. The _JSI_ is an interface that allows a JavaScript object to hold a reference to a C++ and viceversa. +The New Architecture dropped the concept of _The Bridge_ in favor of another communication mechanism: the _JavaScript Interface (JSI)_. The _JSI_ is an interface that allows a JavaScript object to hold a reference to a C++ and vice-versa. Once an object has a reference to the other one, it can directly invoke methods on it. So, for example, a C++ object can now ask a JavaScript object to execute a method in the JavaScript world and viceversa. -This idea allowed to unlock several benefits: +This idea allowed the unlocking of several benefits: -- **Synchronous execution:** it is now possibile to execute synchronously those functions that should not have been asynchronous in the first place. -- **Concurrency:** it is possible from JavaScript to invoke functions that are executed on different thread. -- **Lower overhead:** the New Architecture don't have to serialize/deserialize the data anymore, therefore there are no serialization taxes to pay. -- **Code sharing:** by introducing C++, it is now possible to abstract all the platform agnostic code and to share it with ease between the plaforms. -- **Type safety:** to make sure that JS can properly invoke methods on C++ objects and viceversa, a layer of code automatically generated has been added. The code is generated starting from some JS specification that must be typed through Flow or TypeScript. +- **Synchronous execution:** it is now possible to execute synchronously those functions that should not have been asynchronous in the first place. +- **Concurrency:** it is possible from JavaScript to invoke functions that are executed on different threads. +- **Lower overhead:** the New Architecture doesn't have to serialize/deserialize the data anymore; therefore there are no serialization taxes to pay. +- **Code sharing:** by introducing C++, it is now possible to abstract all the platform agnostic code and to share it with ease between the platforms. +- **Type safety:** to make sure that JS can properly invoke methods on C++ objects and vice-versa, a layer of code automatically generated has been added. The code is generated starting from some JS specification that must be typed through Flow or TypeScript. -These advantages are the foundations of the [TurboModule](pillars-turbomodules) system and a jumping stone to further enhancements. For example, it has been possible to develop a new renderer which is faster and more performant: [Fabric](/architecture/fabric-renderer) and its [Fabric Components](pillars-fabric-components). +These advantages are the foundations of the [TurboModule](pillars-turbomodules) system and a jumping stone to further enhancements. For example, it has been possible to develop a new renderer that is faster and more performant: [Fabric](/architecture/fabric-renderer) and its [Fabric Components](pillars-fabric-components). ## Further Reading -For a technical overview of the New Architecture, have a look at the [Architecture tab](/architecture/overview). +For a technical overview of the New Architecture, read the [Architecture tab](/architecture/overview). -For more information on the Fabric Renderer, have a look at the [Fabric section](/architecture/fabric-renderer). +For more information on the Fabric Renderer, read the [Fabric section](/architecture/fabric-renderer). From 4a3b02c823728041b4b3d981e2bfb1f21c7fbc81 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Fri, 9 Sep 2022 12:03:13 +0100 Subject: [PATCH 15/88] [New Architecture][iOS][0.71.0] Update the App Migration section (#3268) --- docs/hermes.md | 12 ++ docs/new-architecture-app-intro.md | 167 ++++++++--------- docs/new-architecture-app-modules-ios.md | 173 ------------------ docs/new-architecture-app-renderer-ios.md | 93 ---------- docs/new-architecture-intro.md | 2 - docs/react-18-and-react-native.md | 1 - .../pillars-turbomodule.md | 2 +- docs/the-new-architecture/use-app-template.md | 3 +- website/sidebars.json | 4 +- website/static/_redirects | 4 + 10 files changed, 92 insertions(+), 369 deletions(-) delete mode 100644 docs/new-architecture-app-modules-ios.md delete mode 100644 docs/new-architecture-app-renderer-ios.md diff --git a/docs/hermes.md b/docs/hermes.md index cd6b6c9eaf4..14a7bfa7150 100644 --- a/docs/hermes.md +++ b/docs/hermes.md @@ -36,6 +36,18 @@ Edit your `android/app/build.gradle` file and make the change illustrated below: - enableHermes: false // clean and rebuild if changing + enableHermes: true // clean and rebuild if changing ] + +// ... + +if (enableHermes) { +- def hermesPath = "../../node_modules/hermes-engine/android/"; +- debugImplementation files(hermesPath + "hermes-debug.aar") +- releaseImplementation files(hermesPath + "hermes-release.aar") ++ //noinspection GradleDynamicVersion ++ implementation("com.facebook.react:hermes-engine:+") { // From node_modules ++ exclude group:'com.facebook.fbjni' ++ } +} else { ``` Also, if you're using ProGuard, you will need to add these rules in `proguard-rules.pro` : diff --git a/docs/new-architecture-app-intro.md b/docs/new-architecture-app-intro.md index 2b872ced579..2b1de555728 100644 --- a/docs/new-architecture-app-intro.md +++ b/docs/new-architecture-app-intro.md @@ -13,21 +13,29 @@ There are a few prerequisites that should be addressed before the New Architectu React Native released the support for the New Architecture with the release `0.68.0`. -This guide is written with the expectation that you’re using the latest React Native release. At the moment of writing, this is `0.70.0`. Besides this guide, you can leverage the [upgrade helper](https://react-native-community.github.io/upgrade-helper/) to determine what other changes may be required for your project. +This guide is written with the expectation that you’re using the latest React Native release. At the moment of writing, this is `0.71.0`. Beside this guide, you can leverage the [upgrade helper](https://react-native-community.github.io/upgrade-helper/) to determine what other changes may be required for your project. To update to the most recent version of React Native, you can run this command: ```bash -yarn add react-native@0.70.0 +npx react-native upgrade ``` -Starting from React Native `0.69.0`, you may also need to update the version of React to 18. You can do so by using this command: +## Use Hermes -```bash -yarn add react@18.0.0 -``` +Hermes is an open-source JavaScript engine optimized for React Native. Hermes is enabled by default, and you have to explicitly disable it if you want to use JSC. + +We highly recommend using Hermes in your application. With Hermes enabled, you can use the JavaScript debugger in Flipper to directly debug your JavaScript code. -### Android Specifics +Please [follow the instructions on the React Native website](hermes) to learn how to enable/disable Hermes. + +:::caution + +**iOS:** If you opt out of using Hermes, you will need to replace `HermesExecutorFactory` with `JSCExecutorFactory` in any examples used throughout the rest of this guide. + +::: + +## Android - Update Build System Using the New Architecture on Android has some prerequisites that you need to meet: @@ -149,63 +157,27 @@ dependencies { + implementation project(":ReactAndroid") // From node_modules ``` -## Use Hermes - -Hermes is an open-source JavaScript engine optimized for React Native. Hermes is enabled by default, and you have to explicitly disable it if you want to use JSC. - -We highly recommend using Hermes in your application. With Hermes enabled, you will be able to use the JavaScript debugger in Flipper to directly debug your JavaScript code. - -Please [follow the instructions on the React Native website](hermes) to learn how to enable/disable Hermes. - -:::caution - -**iOS:** If you opt-out of using Hermes, you will need to replace `HermesExecutorFactory` with `JSCExecutorFactory` in any examples used throughout the rest of this guide. +## iOS - Build the Project -::: - -### Android +After upgrading the project, there are a few changes you need to apply: -To enable Hermes in Android, open the `android/app/build.gradle` and apply the following changes: +1. Target the proper iOS version. Open the `Podfile` and apply this change: ```diff -project.ext.react = [ -- enableHermes: true, // clean and rebuild if changing -+ enableHermes: true, // clean and rebuild if changing -] -// ... - -} - -if (enableHermes) { -- def hermesPath = "../../node_modules/hermes-engine/android/"; -- debugImplementation files(hermesPath + "hermes-debug.aar") -- releaseImplementation files(hermesPath + "hermes-release.aar") -+ //noinspection GradleDynamicVersion -+ implementation("com.facebook.react:hermes-engine:+") { // From node_modules -+ exclude group:'com.facebook.fbjni' -+ } -} else { -``` - -Moreover, you'll need to update the `proguard-rules`, adding the following ones: - -``` --keep class com.facebook.hermes.unicode.** { *; } --keep class com.facebook.jni.** { *; } +- platform :ios, '11.0' ++ platform :ios, '12.4' ``` -After that, remember to cleanup the project, running +2. Create an `.xcode.env` file to export the locaion of the NODE_BINARY. Navigate to the `ios` folder and run this command: ```sh -cd android -./gradlew clean +echo 'export NODE_BINARY=$(command -v node)' > .xcode.env ``` -## iOS: Build the Project - -After upgrading the project, there are a few changes you need to apply: +If you need it, you can also open the file and replace the `$(command -v node)` with the path to the node executable. +React Native also supports a local version of this file `.xcode.env.local`. This file is not synced with the repository to let you customize your local setup, if it differs from the Continuous Integration or the team one. -1. Fix an API change in the `AppDelegate.m`. Open this file and apply this change: +2. Fix an API change in the `AppDelegate.m`. Open this file and apply this change: ```diff #if DEBUG @@ -214,67 +186,74 @@ After upgrading the project, there are a few changes you need to apply: #else ``` -2. Target the proper iOS version. Open the `Podfile` and apply this change: +## iOS - Use Objective-C++ (`.mm` extension) -```diff -- platform :ios, '11.0' -+ platform :ios, '12.4' -``` - -3. Create an `.xcode.env` file to export the locaion of the NODE_BINARY. Navigate to the `ios` folder and run this command: +TurboModules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. -```sh -echo 'export NODE_BINARY=$(command -v node)' > .xcode.env -``` +:::important -If you need it, you can also open the file and replace the `$(command -v node)` with the path to the node executable. -React Native also supports a local version of this file `.xcode.env.local`. This file is not synced with the repository to let you customize your local setup, if it differs from the Continuous Integration or the team one. +**Use Xcode to rename existing files** to ensure file references persist in your project. You might need to clean the build folder (_Project → Clean Build Folder_) before re-building the app. If the file is renamed outside of Xcode, you may need to click on the old `.m` file reference and Locate the new file. -## iOS: Use Objective-C++ (`.mm` extension) +::: -TurboModules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. +## iOS - Make your AppDelegate conform to `RCTAppDelegate` -:::info +The final step to configure iOS for the New Architecture is to extend a base class proided by React Native, called `RCTAppDelegate`. -Use Xcode to rename existing files to ensure file references persist in your project. You might need to clean the build folder (_Project → Clean Build Folder_) before re-building the app. If the file is renamed outside of Xcode, you may need to click on the old `.m` file reference and Locate the new file. +This class provides a base implementation for all the required functionalities of the new architecture. If you need to customize some of them, you can override those methods, invoke `[super methodNameWith:parameters:];` collecting the returned value and customize the bits you need to customize. -::: +1. Open the `ios/AppDelegate.h` file and update it as it follows: -## iOS: TurboModules: Ensure your App Provides an `RCTCxxBridgeDelegate` +```diff +- #import ++ #import +#import -In order to set up the TurboModule system, you will add some code to interact with the bridge in your AppDelegate. Before you start, go ahead and rename your AppDelegate file to use the `.mm` extension. +- @interface AppDelegate : UIResponder ++ @interface AppDelegate : RCTAppDelegate -Now you will have your AppDelegate conform to `RCTCxxBridgeDelegate`. Start by adding the following imports at the top of your AppDelegate file: +- @property (nonatomic, strong) UIWindow *window; -```objc -#import -#import -#import +@end ``` -Then, declare your app delegate as a `RCTCxxBridgeDelegate` provider: +2. Open the `ios/AppDelegate.mm` file and replace its content with the following: ```objc -@interface AppDelegate () { - // ... +#import "AppDelegate.h" +#import + +@implementation AppDelegate + - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + self.moduleName = @"NameOfTheApp"; + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge +{ +#if DEBUG + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; +#else + return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; +#endif } + +- (BOOL)concurrentRootEnabled +{ + return true; +} + @end ``` -To conform to the `RCTCxxBridgeDelegate` protocol, you must implement the `jsExecutorFactoryForBridge:` method. Typically, this is where you would return a `JSCExecutorFactory` or `HermesExecutorFactory`, and we will use it to install our TurboModules bindings later on. - -You can implement the `jsExecutorFactoryForBridge:` method like this: +:::note +The `moduleName` has to be the same string used in the `[RCTRootView initWithBridge:moduleName:initialProperties]` call in the original `AppDelegate.mm` file. +::: -```objc -#pragma mark - RCTCxxBridgeDelegate +## iOS - Run pod install -- (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge -{ - return std::make_unique(facebook::react::RCTJSIExecutorRuntimeInstaller([bridge](facebook::jsi::Runtime &runtime) { - if (!bridge) { - return; - } - }) - ); -} +```bash +// Run pod install with the flags +RCT_NEW_ARCH_ENABLED=1 pod install ``` diff --git a/docs/new-architecture-app-modules-ios.md b/docs/new-architecture-app-modules-ios.md deleted file mode 100644 index ca6f9306a1c..00000000000 --- a/docs/new-architecture-app-modules-ios.md +++ /dev/null @@ -1,173 +0,0 @@ ---- -id: new-architecture-app-modules-ios -title: Enabling TurboModule on iOS ---- - -import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; - - - -Make sure your application meets all the [prerequisites](new-architecture-app-intro). - -## 1. Provide a TurboModuleManager Delegate - -Add the following imports at the top of your bridge delegate (e.g. `AppDelegate.mm`): - -```objc -#import -#import -``` - -You will also need to declare that your AppDelegate conforms to the `RCTTurboModuleManagerDelegate` protocol, as well as create an instance variable for our Turbo Module manager: - -```objc -@interface AppDelegate () { - // ... - RCTTurboModuleManager *_turboModuleManager; -} -@end -``` - -To conform to the `RCTTurboModuleManagerDelegate` protocol, you will implement these three methods: - -- `getModuleClassFromName:` - This method should return the Class for a native module. You may use the `RCTCoreModulesClassProvider()` method to handle the default, core modules. -- `getTurboModule:jsInvoker:` - This should return `nullptr`. This method may be used later to support C++ TurboModules. -- `getModuleInstanceFromClass:moduleClass:` - This method allows you to perform any side-effects when your TurboModules are initialized. This is the TurboModule analogue to your bridge delegate’s `extraModulesForBridge` method. At this time, you’ll need to initialize the default RCTNetworking and RCTImageLoader modules as indicated below. - -#### TurboModuleManagerDelegate Example - -Take note of `getModuleInstanceFromClass:` in the following example, as it includes some necessary instantiation of several core modules that you will need to include in your application. Eventually, this may not be required. - -```objc title='AppDelegate.mm' -// ... - -#import -#import -#import -#import -#import -#import -#import - -#import - -#import - -// ... - -#pragma mark RCTTurboModuleManagerDelegate - -- (Class)getModuleClassFromName:(const char *)name -{ - return RCTCoreModulesClassProvider(name); -} - -- (std::shared_ptr) - getTurboModule:(const std::string &)name - jsInvoker:(std::shared_ptr)jsInvoker { - return nullptr; -} - -- (id)getModuleInstanceFromClass:(Class)moduleClass -{ - // Set up the default RCTImageLoader and RCTNetworking modules. - if (moduleClass == RCTImageLoader.class) { - return [[moduleClass alloc] initWithRedirectDelegate:nil - loadersProvider:^NSArray> *(RCTModuleRegistry * moduleRegistry) { - return @ [[RCTLocalAssetImageLoader new]]; - } - decodersProvider:^NSArray> *(RCTModuleRegistry * moduleRegistry) { - return @ [[RCTGIFImageDecoder new]]; - }]; - } else if (moduleClass == RCTNetworking.class) { - return [[moduleClass alloc] - initWithHandlersProvider:^NSArray> *( - RCTModuleRegistry *moduleRegistry) { - return @[ - [RCTHTTPRequestHandler new], - [RCTDataRequestHandler new], - [RCTFileRequestHandler new], - ]; - }]; - } - // No custom initializer here. - return [moduleClass new]; -} -``` - -## 2. Install TurboModuleManager JavaScript Bindings - -Next, you will create a `RCTTurboModuleManager` in your bridge delegate’s `jsExecutorFactoryForBridge:` method, and install the JavaScript bindings: - -```objc -#pragma mark - RCTCxxBridgeDelegate - -- (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge -{ - // Add these lines to create a TurboModuleManager - if (RCTTurboModuleEnabled()) { - _turboModuleManager = - [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:self - jsInvoker:bridge.jsCallInvoker]; - - // Necessary to allow NativeModules to lookup TurboModules - [bridge setRCTTurboModuleRegistry:_turboModuleManager]; - - if (!RCTTurboModuleEagerInitEnabled()) { - /** - * Instantiating DevMenu has the side-effect of registering - * shortcuts for CMD + d, CMD + i, and CMD + n via RCTDevMenu. - * Therefore, when TurboModules are enabled, we must manually create this - * NativeModule. - */ - [_turboModuleManager moduleForName:"DevMenu"]; - } - } - - // Add this line... - __weak __typeof(self) weakSelf = self; - - // If you want to use the `JSCExecutorFactory`, remember to add the `#import ` - // import statement on top. - return std::make_unique( - facebook::react::RCTJSIExecutorRuntimeInstaller([weakSelf, bridge](facebook::jsi::Runtime &runtime) { - if (!bridge) { - return; - } - - // And add these lines to install the bindings... - __typeof(self) strongSelf = weakSelf; - if (strongSelf) { - facebook::react::RuntimeExecutor syncRuntimeExecutor = - [&](std::function &&callback) { callback(runtime); }; - [strongSelf->_turboModuleManager installJSBindingWithRuntimeExecutor:syncRuntimeExecutor]; - } - })); -} -``` - -## 3. Enable TurboModule System - -Finally, enable TurboModules in your app by executing the following statement before React Native is initialized in your app delegate (e.g. within `didFinishLaunchingWithOptions:`): - -```objc -RCTEnableTurboModule(YES); -``` - -#### Example - -```objc -@implementation AppDelegate -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - RCTEnableTurboModule(YES); - - RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self - launchOptions:launchOptions]; - - // ... - - return YES; -} -``` diff --git a/docs/new-architecture-app-renderer-ios.md b/docs/new-architecture-app-renderer-ios.md deleted file mode 100644 index 39f3226f55f..00000000000 --- a/docs/new-architecture-app-renderer-ios.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: new-architecture-app-renderer-ios -title: Enabling Fabric on iOS ---- - -import M1Cocoapods from './\_markdown-m1-cocoapods.mdx'; -import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; - - - -This section will go over how to enable the new renderer in your app. Make sure your application meets all the [prerequisites](new-architecture-app-intro). - -## 1. Enable Fabric in Podfile - -Add changes to your Podfile. You can see some examples in [RNTester](https://github.com/facebook/react-native/blob/main/packages/rn-tester/Podfile) and [rn-demo-app](https://github.com/facebook/fbt/blob/rn-demo-app/ios/Podfile). - -```ruby title="Podfile" -# Add the following line at the top of Podfile. -# Codegen produces files/classes that share names, and it will show the warning. -# deterministic_uuids option surpresses the warning. -install! 'cocoapods', :deterministic_uuids => false -target 'Some App' do - pods() -end -def pods() - # Get config - config = use_native_modules! - # Use env variables to turn it on/off. - fabric_enabled = ENV['USE_FABRIC'] - use_react_native!( - ... - # Modify here if your app root path isn't the same as this one. - :app_path => "#{Dir.pwd}/..", - # Pass the flag to enable fabric to use_react_native!. - :fabric_enabled => fabric_enabled - ) -end -``` - -## 2. Update your root view - -How to render your app with Fabric depends on your setup. Here is an example of how you can enable Fabric in your app with the `RN_FABRIC_ENABLED` compiler flag to enable/disable. Refer [RN-Tester’s AppDelegate](https://github.com/facebook/react-native/blob/main/packages/rn-tester/RNTester/AppDelegate.mm) as an example. - -```objc title="AppDelegate.mm" -#ifdef RN_FABRIC_ENABLED -#import -#import -#import -#import -#endif - -@interface AppDelegate () { -#ifdef RN_FABRIC_ENABLED - RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; - std::shared_ptr _reactNativeConfig; - facebook::react::ContextContainer::Shared _contextContainer; -#endif - - // Find a line that define rootView and replace/edit with the following lines. - -#ifdef RN_FABRIC_ENABLED - _contextContainer = std::make_shared(); - _reactNativeConfig = std::make_shared(); - - _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); - - _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] - initWithBridge:bridge - contextContainer:_contextContainer]; - - bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; - - UIView *rootView = - [[RCTFabricSurfaceHostingProxyRootView alloc] initWithBridge:bridge - moduleName:<#moduleName#> - initialProperties:@{}]; -#else - // Current implementation to define rootview. - RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge - moduleName:<#moduleName#> - initialProperties:@{}]; -#endif -``` - -## 3. Run pod install - -```bash -// Run pod install with the flags -USE_FABRIC=1 RCT_NEW_ARCH_ENABLED=1 pod install -``` - - diff --git a/docs/new-architecture-intro.md b/docs/new-architecture-intro.md index fa88aeb9e8d..68e44846a56 100644 --- a/docs/new-architecture-intro.md +++ b/docs/new-architecture-intro.md @@ -24,10 +24,8 @@ The guide is divided into five sections: - [Prerequisites for Supporting the New Architecture in your App](new-architecture-app-intro) - Enabling the New NativeModule System (TurboModule) in your App - [Android](new-architecture-app-modules-android) - - [iOS](new-architecture-app-modules-ios) - Enabling the New Renderer (Fabric) in your App - [Android](new-architecture-app-renderer-android) - - [iOS](new-architecture-app-renderer-ios) - [**React 18 & React Native**](react-18-and-react-native) - [**Troubleshooting**](new-architecture-troubleshooting) - [**Appendix**](new-architecture-appendix) diff --git a/docs/react-18-and-react-native.md b/docs/react-18-and-react-native.md index ed4a5d09eb6..acbe7874440 100644 --- a/docs/react-18-and-react-native.md +++ b/docs/react-18-and-react-native.md @@ -110,7 +110,6 @@ On iOS, you'll have access to the `concurrentRootEnabled` method on your `AppDel /// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { - // Switch this bool to turn on and off the concurrent root return true; } ``` diff --git a/docs/the-new-architecture/pillars-turbomodule.md b/docs/the-new-architecture/pillars-turbomodule.md index b5afb3952ed..9452acaf086 100644 --- a/docs/the-new-architecture/pillars-turbomodule.md +++ b/docs/the-new-architecture/pillars-turbomodule.md @@ -17,7 +17,7 @@ TurboModules are the next iteration on Native Modules that provide a few extra [ - Lazy loading of modules, allowing for faster app startup - The use of JSI, a JavaScript interface for native code, allows for more efficient communication between native and JavaScript code than the bridge -This guide will show you how to create a basic TurboModule. +This guide will show you how to create a basic TurboModule compatible with React Native 0.70.0. :::caution TurboModules only work with the **New Architecture** enabled. diff --git a/docs/the-new-architecture/use-app-template.md b/docs/the-new-architecture/use-app-template.md index 50b82a1b20f..8abd06fb9a8 100644 --- a/docs/the-new-architecture/use-app-template.md +++ b/docs/the-new-architecture/use-app-template.md @@ -128,5 +128,4 @@ For further explanations of what each file is doing, check out these guides to w #### iOS -- [Enabling TurboModules on iOS](new-architecture-app-modules-ios.md) -- [Enabling Fabric on iOS](new-architecture-app-renderer-ios.md) +- [Enabling The New Architecture in Your App](new-architecture-app-intro.md) diff --git a/website/sidebars.json b/website/sidebars.json index 56db20c5502..504f2d8947a 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -130,9 +130,7 @@ "items": [ "new-architecture-app-intro", "new-architecture-app-modules-android", - "new-architecture-app-modules-ios", - "new-architecture-app-renderer-android", - "new-architecture-app-renderer-ios" + "new-architecture-app-renderer-android" ] }, "react-18-and-react-native", diff --git a/website/static/_redirects b/website/static/_redirects index 49f6076c6bf..d5fa4b353c5 100644 --- a/website/static/_redirects +++ b/website/static/_redirects @@ -15,6 +15,10 @@ # Changed blog post dates /blog/2021/03/11/version-0.64 /blog/2021/03/12/version-0.64 +# Removed pages +/docs/new-architecture-app-modules-ios /docs/new-architecture-intro +/docs/new-architecture-app-renderer-ios /docs/new-architecture-intro + # Architecture pages move to unversioned docs /docs/architecture-overview /architecture/overview /docs/fabric-renderer /architecture/fabric-renderer From 42e0266b0c8b93c883b0253ae0f4c1fe825630e9 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Fri, 9 Sep 2022 12:21:24 +0100 Subject: [PATCH 16/88] fix: Address missing feedback from prev PR (#3312) --- docs/new-architecture-intro.md | 7 +++---- docs/react-18-and-react-native.md | 1 + .../version-0.70/new-architecture-app-intro.md | 8 +------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/docs/new-architecture-intro.md b/docs/new-architecture-intro.md index 68e44846a56..fce2e38630b 100644 --- a/docs/new-architecture-intro.md +++ b/docs/new-architecture-intro.md @@ -22,10 +22,9 @@ The guide is divided into five sections: - [iOS](new-architecture-library-ios) - **Supporting the New Architecture in your App** - [Prerequisites for Supporting the New Architecture in your App](new-architecture-app-intro) - - Enabling the New NativeModule System (TurboModule) in your App - - [Android](new-architecture-app-modules-android) - - Enabling the New Renderer (Fabric) in your App - - [Android](new-architecture-app-renderer-android) + - Android + - [Enabling the New NativeModule System (TurboModule) in your App](new-architecture-app-modules-android) + - [Enabling the New Renderer (Fabric) in your App](new-architecture-app-renderer-android) - [**React 18 & React Native**](react-18-and-react-native) - [**Troubleshooting**](new-architecture-troubleshooting) - [**Appendix**](new-architecture-appendix) diff --git a/docs/react-18-and-react-native.md b/docs/react-18-and-react-native.md index acbe7874440..ed4a5d09eb6 100644 --- a/docs/react-18-and-react-native.md +++ b/docs/react-18-and-react-native.md @@ -110,6 +110,7 @@ On iOS, you'll have access to the `concurrentRootEnabled` method on your `AppDel /// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`. - (BOOL)concurrentRootEnabled { + // Switch this bool to turn on and off the concurrent root return true; } ``` diff --git a/website/versioned_docs/version-0.70/new-architecture-app-intro.md b/website/versioned_docs/version-0.70/new-architecture-app-intro.md index dc7948d4dff..b0b0b519a60 100644 --- a/website/versioned_docs/version-0.70/new-architecture-app-intro.md +++ b/website/versioned_docs/version-0.70/new-architecture-app-intro.md @@ -18,13 +18,7 @@ This guide is written with the expectation that you’re using the latest React To update to the most recent version of React Native, you can run this command: ```bash -yarn add react-native@0.70.0 -``` - -Starting from React Native `0.69.0`, you may also need to update the version of React to 18. You can do so by using this command: - -```bash -yarn add react@18.0.0 +npx react-native upgrade ``` ### Android specifics From 54d266b7842e1dda86b5877466f6a61fcf5bf043 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 9 Sep 2022 15:08:43 +0100 Subject: [PATCH 17/88] Clarify New Architecture Terminology (#3308) --- docs/new-architecture-app-intro.md | 2 +- docs/new-architecture-app-modules-android.md | 10 +-- docs/new-architecture-app-renderer-android.md | 2 +- docs/new-architecture-appendix.md | 17 +++-- docs/new-architecture-intro.md | 4 +- docs/new-architecture-library-intro.md | 6 +- docs/new-architecture-library-ios.md | 2 +- docs/react-18-and-react-native.md | 2 +- .../_markdown_native_deprecation.mdx | 2 +- ...ackward-compatibility-fabric-components.md | 47 ++++++------ .../backward-compatibility-turbomodules.md | 45 +++++++----- .../backward-compatibility.md | 6 +- docs/the-new-architecture/landing-page.md | 6 +- docs/the-new-architecture/pillars-codegen.md | 72 +++++++++++++++---- .../pillars-fabric-components.md | 46 ++++++------ .../pillars-turbomodule.md | 48 ++++++------- docs/the-new-architecture/pillars.md | 17 +++-- docs/the-new-architecture/use-app-template.md | 4 +- docs/the-new-architecture/why.md | 2 +- 19 files changed, 206 insertions(+), 134 deletions(-) diff --git a/docs/new-architecture-app-intro.md b/docs/new-architecture-app-intro.md index 2b1de555728..c0d56f91a71 100644 --- a/docs/new-architecture-app-intro.md +++ b/docs/new-architecture-app-intro.md @@ -188,7 +188,7 @@ React Native also supports a local version of this file `.xcode.env.local`. This ## iOS - Use Objective-C++ (`.mm` extension) -TurboModules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. +Turbo Native Modules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. :::important diff --git a/docs/new-architecture-app-modules-android.md b/docs/new-architecture-app-modules-android.md index b3e8fddfb7c..02069ffac51 100644 --- a/docs/new-architecture-app-modules-android.md +++ b/docs/new-architecture-app-modules-android.md @@ -100,7 +100,7 @@ yarn react-native run-android ## 2. Java/Kotlin - Provide a `ReactPackageTurboModuleManagerDelegate` -Now is time to actually use the TurboModule. +Now is time to actually use the Turbo Native Module. First, we will need to create a `ReactPackageTurboModuleManagerDelegate` subclass, like the following: @@ -193,7 +193,7 @@ protected constructor( Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `project()` inside the `CMakeLists.txt` file you created before. -This class will then be responsible of loading the TurboModules and will take care of loading the native library build with the NDK at runtime. +This class will then be responsible of loading the Turbo Native Modules and will take care of loading the native library build with the NDK at runtime. ## 3. Adapt your `ReactNativeHost` to use the `ReactPackageTurboModuleManagerDelegate` @@ -259,7 +259,7 @@ class MyApplication : Application(), ReactApplication { ## 4. Extend the `getPackages()` from your `ReactNativeHost` to use the TurboModule -Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created TurboModule. Update the method to include the following: +Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created Turbo Native Module. Update the method to include the following: @@ -493,7 +493,7 @@ std::shared_ptr MyApplicationModuleProvider(const std::string modul Please adapt the `samplelibrary.h` import to match the same library name you provided when building the apps. This is the C++ generated file that is created by the codegen. -Here you can also specify more than one provider, should you have more than one TurboModule. Specifically in this example we look for a TurboModule from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). +Here you can also specify more than one provider, should you have more than one Turbo Native Module. Specifically in this example we look for a Turbo Native Module from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). ```cpp #include "MyApplicationModuleProvider.h" @@ -532,7 +532,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { ## 6. Enable the `useTurboModules` flag in your Application `onCreate` -Now you can finally enable the `TurboModule `support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. +Now you can finally enable the `Turbo Native Module` support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. diff --git a/docs/new-architecture-app-renderer-android.md b/docs/new-architecture-app-renderer-android.md index 736abcb8f56..39bb732efbf 100644 --- a/docs/new-architecture-app-renderer-android.md +++ b/docs/new-architecture-app-renderer-android.md @@ -113,7 +113,7 @@ LOG Running "App" with {"fabric":true,"initialProps":{},"rootTag":1} ## Migrating Android ViewManagers -First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. +First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (Turbo Module) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. ### JavaScript changes diff --git a/docs/new-architecture-appendix.md b/docs/new-architecture-appendix.md index 56b3301423b..61bbc1377e3 100644 --- a/docs/new-architecture-appendix.md +++ b/docs/new-architecture-appendix.md @@ -7,7 +7,16 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; -## I. Flow Type to Native Type Mapping +## I. Terminology + +The whole New Architecture related guides will stick to the following **terminology**: + +- **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. +- **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. +- **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Architecture, namely the new renderer. For brevity you might find them referred as **Fabric Components**. +- **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Architecture, namely the new Native Module System. For brevity you might find them referred as **Turbo Modules** + +## II. Flow Type to Native Type Mapping You may use the following table as a reference for which types are supported and what they map to in each platform: @@ -85,7 +94,7 @@ Callback functions are not type checked, and are generalized as `Object`s. You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository. ::: -## II. TypeScript to Native Type Mapping +## III. TypeScript to Native Type Mapping You may use the following table as a reference for which types are supported and what they map to in each platform: @@ -105,7 +114,7 @@ You may use the following table as a reference for which types are supported and You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository. -## III. Invoking the code-gen during development +## IV. Invoking the code-gen during development > This section contains information specific to v0.66 of React Native. @@ -182,7 +191,7 @@ node node_modules/react-native/scripts/generate-specs-cli.js \ In the above example, the code-gen script will generate several files: `MyLibSpecs.h` and `MyLibSpecs-generated.mm`, as well as a handful of `.h` and `.cpp` files, all located in the `ios` directory. -## IV. Note on Existing Apps +## V. Note on Existing Apps This guide provides instructions for migrating an application that is based on the default app template that is provided by React Native. If your app has deviated from the template, or you are working with an application that was never based off the template, then the following sections might help. diff --git a/docs/new-architecture-intro.md b/docs/new-architecture-intro.md index fce2e38630b..e5b224a1649 100644 --- a/docs/new-architecture-intro.md +++ b/docs/new-architecture-intro.md @@ -9,7 +9,7 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; # Getting Started with the New Architecture -This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **new NativeModule system (TurboModule) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps. +This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **New Native Module system (Turbo Module) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps. ## Table of Contents @@ -23,7 +23,7 @@ The guide is divided into five sections: - **Supporting the New Architecture in your App** - [Prerequisites for Supporting the New Architecture in your App](new-architecture-app-intro) - Android - - [Enabling the New NativeModule System (TurboModule) in your App](new-architecture-app-modules-android) + - [Enabling the New Native Module System (Turbo Module) in your App](new-architecture-app-modules-android) - [Enabling the New Renderer (Fabric) in your App](new-architecture-app-renderer-android) - [**React 18 & React Native**](react-18-and-react-native) - [**Troubleshooting**](new-architecture-troubleshooting) diff --git a/docs/new-architecture-library-intro.md b/docs/new-architecture-library-intro.md index 9d688a8151e..0d905261fb7 100644 --- a/docs/new-architecture-library-intro.md +++ b/docs/new-architecture-library-intro.md @@ -23,7 +23,7 @@ Currently, this guide is written under the assumption that you will be using [Fl To adopt the New Architecture, you start by creating these specs for your native modules and native components. You can do this prior to actually migrating to the New Architecture: the specs will be used later on to generate native interface code for all the supported platforms as a way to enforce uniform APIs across platforms. -#### Turbomodules +#### Turbo Native Modules JavaScript spec files **must** be named `Native.js` and they export a `TurboModuleRegistry` `Spec` object. The name convention is important because the Codegen process looks for modules whose `js` (`jsx`, `ts`, or `tsx`) spec file starts with the keyword `Native`. @@ -70,7 +70,7 @@ export default TurboModuleRegistry.get(''); -#### Fabric Components +#### Fabric Native Components JavaScript spec files **must** be named `NativeComponent.js` (for TypeScript use extension `.ts` or `.tsx`) and they export a `HostComponent` object. The name convention is important: the Codegen process looks for components whose spec file (either JavaScript or TypeScript) ends with the suffix `NativeComponent`. @@ -214,7 +214,7 @@ Codegen can be configured in the `package.json` file of your Library. Add the fo - The `codegenConfig` is the key used by the Codegen to verify that there is some code to generate. - The `name` field is the name of the library. -- The `type` field is used to identify the type of module we want to create. Our suggestion is to keep `all` to support libraries that contain both TurboModule and Fabric Components. +- The `type` field is used to identify the type of module we want to create. Our suggestion is to keep `all` to support libraries that contain both Turbo Native Module and Fabric Native Components. - The `jsSrcsDir` is the directory where the codegen will start looking for JavaScript specs. - The `android.javaPackageName` is the name of the package where the generated code wil end up. diff --git a/docs/new-architecture-library-ios.md b/docs/new-architecture-library-ios.md index 8eca9aa3184..1fb8eee0851 100644 --- a/docs/new-architecture-library-ios.md +++ b/docs/new-architecture-library-ios.md @@ -32,7 +32,7 @@ Pod::Spec.new do |s| } s.dependency "React-Core" - s.dependency "React-RCTFabric" # This is for Fabric Component + s.dependency "React-RCTFabric" # This is for Fabric Native Component s.dependency "React-Codegen" s.dependency "RCT-Folly" s.dependency "RCTRequired" diff --git a/docs/react-18-and-react-native.md b/docs/react-18-and-react-native.md index ed4a5d09eb6..33892b9e1d6 100644 --- a/docs/react-18-and-react-native.md +++ b/docs/react-18-and-react-native.md @@ -31,7 +31,7 @@ The concurrent features in React 18 are built on top of the new concurrent rende Previous versions of React Native built on the old architecture **cannot** support concurrent rendering or concurrent features. This is because the old architecture relied on mutating the native trees, which doesn’t allow for React to prepare multiple versions of the tree at the same time. -Fortunately, the New Architecture was written bottom-up with concurrent rendering in mind, and is fully compatible with React 18. This means, in order to upgrade to React 18 in your React Native app, your application needs to be migrated to the React Native's New Architecture including Fabric and TurboModules. +Fortunately, the New Architecture was written bottom-up with concurrent rendering in mind, and is fully compatible with React 18. This means, in order to upgrade to React 18 in your React Native app, your application needs to be migrated to the React Native's New Architecture including Fabric Native Components and Turbo Native Modules. ## React 18 enabled by default diff --git a/docs/the-new-architecture/_markdown_native_deprecation.mdx b/docs/the-new-architecture/_markdown_native_deprecation.mdx index 569a078d147..390bfcdc3de 100644 --- a/docs/the-new-architecture/_markdown_native_deprecation.mdx +++ b/docs/the-new-architecture/_markdown_native_deprecation.mdx @@ -1,4 +1,4 @@ :::info Native Module and Native Components are our stable technologies used by the legacy architecture. -They will be deprecated in the future when the New Architecture will be stable. The New Architecture uses [TurboModule](./the-new-architecture/pillars-turbomodules) and [Fabric Components](./the-new-architecture/pillars-fabric-components) to achieve similar results. +They will be deprecated in the future when the New Architecture will be stable. The New Architecture uses [Turbo Native Module](./the-new-architecture/pillars-turbomodules) and [Fabric Native Components](./the-new-architecture/pillars-fabric-components) to achieve similar results. ::: diff --git a/docs/the-new-architecture/backward-compatibility-fabric-components.md b/docs/the-new-architecture/backward-compatibility-fabric-components.md index 64f93c1834f..8f67e7dcc1d 100644 --- a/docs/the-new-architecture/backward-compatibility-fabric-components.md +++ b/docs/the-new-architecture/backward-compatibility-fabric-components.md @@ -1,6 +1,6 @@ --- id: backward-compatibility-fabric-components -title: Fabric Components as Native Components +title: Fabric Components as Legacy Native Components --- import Tabs from '@theme/Tabs'; @@ -12,28 +12,35 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -Creating a backward compatible Fabric Component requires the knowledge of how to create a Fabric Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). +Creating a backward compatible Fabric Native Component requires the knowledge of how to create a Legacy Native Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). -Fabric Components only work when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. +Fabric Native Components only work when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: -Creating a backward compatible Fabric Component lets your users continue to leverage your library independently from the architecture they use. The creation of such a component requires a few steps: +Creating a backward compatible Fabric Native Component lets your users continue to leverage your library independently from the architecture they use. The creation of such a component requires a few steps: 1. Configure the library so that dependencies are prepared to set up properly for both the Old and the New Architecture. 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. +- **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Native Renderer, Fabric. For brevity you might find them referred as **Fabric Components**. + ::: + While the last step is the same for all the platforms, the first two steps are different for iOS and Android. -## Configure the Fabric Component Dependencies +## Configure the Fabric Native Component Dependencies ### iOS -The Apple platform installs Fabric Components using [Cocoapods](https://cocoapods.org) as a dependency manager. +The Apple platform installs Fabric Native Components using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every Fabric Component defines a `podspec` that looks like this: +Every Fabric Native Component defines a `podspec` that looks like this: ```ruby require "json" @@ -104,13 +111,13 @@ This `if` guard prevents the dependencies from being installed when the environm ### Android -To create a module that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. +To create a Native Component that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. :::note Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: -To configure the Fabric Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: +To configure the Fabric Native Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: ```diff title="build.gradle" +// Add this function in case you don't have it already @@ -148,7 +155,7 @@ These changes do three main things: The second step is to instruct Xcode to avoid compiling all the lines using the New Architecture types and files when we are building an app with the Old Architecture. -A Fabric Component requires an header file and an implementation file to add the actual `View` to the module. +A Fabric Native Component requires an header file and an implementation file to add the actual `View` to the module. For example, the `RNMyComponentView.h` header file could look like this: @@ -236,15 +243,15 @@ As we can't use conditional compilation blocks on Android, we will define two di Therefore, you have to: -1. Create a Native Component in the `src/oldarch` path. See [this guide](../native-components-android) to learn how to create a Native Component. -2. Create a Fabric Component in the `src/newarch` path. See [this guide](pillars-fabric-components) to learn how to create a Fabric Component. +1. Create a Legacy Native Component in the `src/oldarch` path. See [this guide](../native-components-android) to learn how to create a Legacy Native Component. +2. Create a Fabric Native Component in the `src/newarch` path. See [this guide](pillars-fabric-components) to learn how to create a Fabric Native Component. and then instruct Gradle to decide which implementation to pick. -Some files can be shared between a Native and a Fabric Component: these should be created or moved into a folder that is loaded by both the architectures. These files are: +Some files can be shared between a Legacy and a Fabric Component: these should be created or moved into a folder that is loaded by both the architectures. These files are: - the `.java` that instantiate and configure the Android View for both the components. -- the `ManagerImpl.java` file where which contains the logic of the ViewManager that can be shared between the Native and the Fabric Component. +- the `ManagerImpl.java` file where which contains the logic of the ViewManager that can be shared between the Legacy and the Fabric Component. - the `Package.java` file used to load the component. The final folder structure looks like this: @@ -275,7 +282,7 @@ my-component └── package.json ``` -The code that should go in the `MyComponentViewManagerImpl.java` and that can be shared between the Native Component and the Fabric Component is, for example: +The code that should go in the `MyComponentViewManagerImpl.java` and that can be shared between the Native Component and the Fabric Native Component is, for example: ```java title="example of MyComponentViewManager.java" package com.MyComponent; @@ -296,7 +303,7 @@ public class MyComponentViewManagerImpl { } ``` -Then, the Native Component and the Fabric Component can be updated using the function declared in the shared manager. +Then, the Native Component and the Fabric Native Component can be updated using the function declared in the shared manager. For example, for a Native Component: @@ -330,7 +337,7 @@ public class MyComponentViewManager extends SimpleViewManager { } ``` -And, for a Fabric Component: +And, for a Fabric Native Component: ```java title="Fabric Component using the ViewManagerImpl" // Use the static NAME property from the shared implementation @@ -381,7 +388,7 @@ For a step-by-step example on how to achieve this, have a look at [this repo](ht The last step makes sure that the JavaScript behaves transparently to chosen architecture. -For a Fabric Component, the source of truth is the `NativeComponent.js` (or `.ts`) spec file. The app accesses the spec file like this: +For a Fabric Native Component, the source of truth is the `NativeComponent.js` (or `.ts`) spec file. The app accesses the spec file like this: ```ts import MyComponent from 'your-component/src/index'; @@ -431,5 +438,5 @@ Whether you are using Flow or TypeScript for your specs, we understand which arc Please note that the New Architecture is still experimental. The `global.nativeFabricUIManager` API might change in the future for a function that encapsulate this check. ::: -- If that object is `null`, then the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). -- If that object is set, the app is running with Fabric enabled, and it should use the `NativeComponent` spec to access the Fabric Component. +- If that object is `null`, then the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Legacy Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). +- If that object is set, the app is running with Fabric enabled, and it should use the `NativeComponent` spec to access the Fabric Native Component. diff --git a/docs/the-new-architecture/backward-compatibility-turbomodules.md b/docs/the-new-architecture/backward-compatibility-turbomodules.md index 9b636d4fb79..590220e6453 100644 --- a/docs/the-new-architecture/backward-compatibility-turbomodules.md +++ b/docs/the-new-architecture/backward-compatibility-turbomodules.md @@ -1,6 +1,6 @@ --- id: backward-compatibility-turbomodules -title: TurboModules as Native Modules +title: Turbo Modules as Legacy Native Modules --- import Tabs from '@theme/Tabs'; @@ -12,7 +12,7 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -Creating a backward compatible TurboModule requires the knowledge of how to create a TurboModule. To recall these concepts, have a look at this [guide](pillars-turbomodules). +Creating a backward compatible Turbo Native Module requires the knowledge of how to create a Legacy Native Module. To recall these concepts, have a look at this [guide](pillars-turbomodules). TurboModules only works when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: @@ -23,17 +23,24 @@ Creating a backward compatible TurboModule lets your users continue to leverage 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. +- **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Native Module System. For brevity you might find them referred as **Turbo Modules**. + ::: + While the last step is the same for all the platforms, the first two steps are different for iOS and Android. -## Configure the TurboModule Dependencies +## Configure the Turbo Native Module Dependencies ### iOS -The Apple platform installs TurboModules using [Cocoapods](https://cocoapods.org) as a dependency manager. +The Apple platform installs Turbo Native Modules using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every TurboModule defines a `podspec` that looks like this: +Every Turbo Native Module defines a `podspec` that looks like this: ```ruby require "json" @@ -109,7 +116,7 @@ To create a module that can work with both architectures, you need to configure Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure the maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: -To configure the TurboModule so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: +To configure the Turbo Native Module so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: ```diff title="build.gradle" +// Add this function in case you don't have it already @@ -156,7 +163,7 @@ The file to change is the module implementation file, which is usually a `` type, generated by The New Architecture. -The **goal** is to make sure that the `TurboModule` still builds with the Old Architecture. To achieve that, we can wrap the `#import ".h"` and the `getTurboModule:` function into an `#ifdef RCT_NEW_ARCH_ENABLED` compilation directive, as shown in the following example: +The **goal** is to make sure that the `Turbo Native Module` still builds with the Old Architecture. To achieve that, we can wrap the `#import ".h"` and the `getTurboModule:` function into an `#ifdef RCT_NEW_ARCH_ENABLED` compilation directive, as shown in the following example: ```diff #import ".h" @@ -181,19 +188,19 @@ This snippet uses the same `RCT_NEW_ARCH_ENABLED` flag used in the previous [sec ### Android -As we can't use conditional compilation blocks on Android, we will define two different source sets. This will allow to create a backward compatible TurboModule with the proper source that is loaded and compiled depending on the used architecture. +As we can't use conditional compilation blocks on Android, we will define two different source sets. This will allow to create a backward compatible Turbo Native Module with the proper source that is loaded and compiled depending on the used architecture. Therefore, you have to: -1. Create a Native Module in the `src/oldarch` path. See [this guide](../native-modules-intro) to learn how to create a Native Module. -2. Create a TurboModule in the `src/newarch` path. See [this guide](./pillars-turbomodules) to learn how to create a TurboModule +1. Create a Legacy Native Module in the `src/oldarch` path. See [this guide](../native-modules-intro) to learn how to create a Legacy Native Module. +2. Create a Turbo Native Module in the `src/newarch` path. See [this guide](./pillars-turbomodules) to learn how to create a Turbo Native Module and then instruct Gradle to decide which implementation to pick. -Some files can be shared between a Native Module and a TurboModule: these should be created or moved into a folder that is loaded by both the architectures. These files are: +Some files can be shared between a Legacy Native Module and a Turbo Native Module: these should be created or moved into a folder that is loaded by both the architectures. These files are: - the `Package.java` file used to load the module. -- a `Impl.java` file where we can put the code that both the Native Module and the TurboModule has to execute. +- a `Impl.java` file where we can put the code that both the Legacy Native Module and the Turbo Native Module has to execute. The final folder structure looks like this: @@ -222,7 +229,7 @@ my-module └── package.json ``` -The code that should go in the `MyModuleImpl.java`, and that can be shared by the Native Module and the TurboModule is, for example: +The code that should go in the `MyModuleImpl.java`, and that can be shared by the Legacy Native Module and the Turbo Native Module is, for example: ```java title="example of MyModuleImple.java" package com.MyModule; @@ -243,13 +250,13 @@ public class MyModuleImpl { } ``` -Then, the Native Module and the TurboModule can be updated with the following steps: +Then, the Legacy Native Module and the Turbo Native Module can be updated with the following steps: 1. Create a private instance of the `MyModuleImpl` class. 2. Initialize the instance in the module constructor. 3. Use the private instance in the modules methods. -For example, for a Native Module: +For example, for a Legacy Native Module: ```java title="Native Module using the Impl module" public class MyModule extends ReactContextBaseJavaModule { @@ -277,7 +284,7 @@ public class MyModule extends ReactContextBaseJavaModule { } ``` -And, for a TurboModule: +And, for a Turbo Native Module: ```java title="TurboModule using the Impl module" public class MyModule extends MyModuleSpec { @@ -313,7 +320,7 @@ For a step-by-step example on how to achieve this, have a look at [this repo](ht The last step makes sure that the JavaScript behaves transparently to chosen architecture. -For a TurboModule, the source of truth is the `Native.js` (or `.ts`) spec file. The app accesses the spec file like this: +For a Turbo Native Module, the source of truth is the `Native.js` (or `.ts`) spec file. The app accesses the spec file like this: ```ts import MyModule from 'your-module/src/index'; @@ -366,5 +373,5 @@ Whether you are using Flow or TypeScript for your specs, we understand which arc The `global.__turboModuleProxy` API may change in the future for a function that encapsulates this check. ::: -- If that object is `null`, the app has not enabled the TurboModule feature. It's running on the Old Architecture, and the fallback is to use the default [`NativeModule` implementation](../native-modules-intro). -- If that object is set, the app is running with the TurboModules enabled, and it should use the `Native` spec to access the TurboModule. +- If that object is `null`, the app has not enabled the Turbo Native Module feature. It's running on the Old Architecture, and the fallback is to use the default [`Legacy Native Module` implementation](../native-modules-intro). +- If that object is set, the app is running with the Turbo Native Modules enabled, and it should use the `Native` spec to access the Turbo Native Module. diff --git a/docs/the-new-architecture/backward-compatibility.md b/docs/the-new-architecture/backward-compatibility.md index 89c1f3ac73f..babe5507485 100644 --- a/docs/the-new-architecture/backward-compatibility.md +++ b/docs/the-new-architecture/backward-compatibility.md @@ -11,7 +11,7 @@ Creating a backward compatible module is important to provide a library that wor The trick to create a good backward compatible module is to minimize the changes required to adopt the new version. In that way, users of the module can smoothly move to the new version and migrate to the New Architecture when they are ready, ideally by issueing one different command. -To achieve this result, we have to perform few changes in our **TurboModule** and **Fabric Component** configurations. The steps we have to follow are: +To achieve this result, we have to perform few changes in our **Turbo Native Module** and **Fabric Native Component** configurations. The steps we have to follow are: 1. **Update the installation configuration** to avoid using code that is not needed by the Old Architecture. 1. **Update the code** to support both architectures. Both Android and iOS build pipelines gives you mechanism to provide a library that will compile with the correct React Native Architecture. @@ -21,5 +21,5 @@ To achieve this result, we have to perform few changes in our **TurboModule** an The next sections requires that you are familiar with the [Pillars](pillars) of the **New Architecture**. ::: -- To create a backward compatible **TurboModule**, follow [this guide](backward-compatibility-turbomodules). -- To create a backward compatible **Fabric Component**, follow [this guide](backward-compatibility-fabric-components). +- To create a backward compatible **Turbo Native Module**, follow [this guide](backward-compatibility-turbomodules). +- To create a backward compatible **Fabric Native Component**, follow [this guide](backward-compatibility-fabric-components). diff --git a/docs/the-new-architecture/landing-page.md b/docs/the-new-architecture/landing-page.md index fd8abf53fcf..e3531bc09c8 100644 --- a/docs/the-new-architecture/landing-page.md +++ b/docs/the-new-architecture/landing-page.md @@ -11,9 +11,9 @@ Starting from version 0.68, React Native provides the New Architecture, which of To achieve these benefits, we had to rethink how Native Modules and Native Components work. This led us to develop the [Pillars of the New Architecture](pillars): -- [TurboModules](pillars-turbomodules), a framework to support efficient and flexible integration with native code -- [Fabric renderer and components](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering -- [Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture via static typing in JavaScript +- [The New Native Module System - Turbo Modules](pillars-turbomodules), a framework to support efficient and flexible integration with native code +- [The New Native Renderer - Fabric](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering +- [The Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture via static typing in JavaScript ## Get Started with the New Architecture diff --git a/docs/the-new-architecture/pillars-codegen.md b/docs/the-new-architecture/pillars-codegen.md index d736c340546..e34013a7c1d 100644 --- a/docs/the-new-architecture/pillars-codegen.md +++ b/docs/the-new-architecture/pillars-codegen.md @@ -11,7 +11,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con The **Codegen** is not a proper pillar, but it is a tool that can be used to avoid writing a lot of repetitive code. Using **Codegen** is not mandatory: all the code that is generated by it can also be written manually. However, it generates scaffolding code that could save you a lot of time. -The **Codegen** is invoked automatically by React Native every time an iOS or Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**TurboModules**](./pillars-turbomodules) and [**Fabric Components**](./pillars-fabric-components), for example. +The **Codegen** is invoked automatically by React Native every time an iOS or Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**Turbo Native Modules**](./pillars-turbomodules) and [**Fabric Native Components**](./pillars-fabric-components), for example. This guide teaches how to configure the **Codegen**, and how to invoke it manually for each platform, and describes the generated code. @@ -35,12 +35,12 @@ Previous versions of React Native uses a version of **Codegen** that requires a Then, add the module that requires the **Codegen** as an NPM dependency of the app: ```sh -yarn add +yarn add ``` -See how to create a [TurboModule](pillars-turbomodules) or a [Fabric Component](pillars-fabric-components) to get more information on how to configure them. +See how to create a [Turbo Native Module](pillars-turbomodules) or a [Fabric Native Component](pillars-fabric-components) to get more information on how to configure them. -The rest of this guide assumes that you have a `TurboModule` and/or a `Fabric Component` properly set up. +The rest of this guide assumes that you have a `Turbo Native Module` and/or a `Fabric Native Component` properly set up. # iOS @@ -58,7 +58,7 @@ node node_modules/react_native/scripts/generate-artifacts.js \ --outputPath \ ``` -Given that the app has `TurboModules` and/or `Fabric Components` configured as a dependency, **Codegen** looks for all of them and generates the code in the path you provided. +Given that the app has `Turbo Native Modules` and/or `Fabric Native Components` configured as a dependency, **Codegen** looks for all of them and generates the code in the path you provided. ## The Generated Code @@ -106,29 +106,50 @@ Then, there is an `ios` folder that contains: - A custom folder for each TurboModule. - The header (`.h`) and implementation (`.mm`) files for the `RCTThirdPartyFabricComponentsProvider`. -- A base `react/renderer/components` folder which contains a custom folder for each `Fabric Component`. +- A base `react/renderer/components` folder which contains a custom folder for each `Fabric Native Component`. -In the example above, there are both a TurboModule and a set of Fabric Components. These are generated by React Native itself: `FBReactNativeSpec` and `rncore`. These modules will always appear even if you don't have any extra TurboModule or Fabric Component: React Native requires them in order to work properly. +In the example above, there are both a TurboModule and a set of Fabric Native Components. These are generated by React Native itself: `FBReactNativeSpec` and `rncore`. These modules will always appear even if you don't have any extra TurboModule or Fabric Native Component: React Native requires them in order to work properly. -### TurboModules +### Turbo Native Modules -Each TurboModule's folder contains two files: an interface file and an implementation file. +Each folder contains two files: an interface file and an implementation file. +<<<<<<< HEAD The interface files have the same name as that of the TurboModule and contain methods to initialize the JSI interface. +||||||| parent of 1f97265d (Clarify New Architecture Terminology) +The interface files have the same name of the TurboModule and they contain methods to initialize the JSI interface. +======= +The interface files have the same name of the Turbo Native Module and they contain methods to initialize the JSI interface. + +> > > > > > > 1f97265d (Clarify New Architecture Terminology) The implementation files, instead, have the `-generated` suffix and contain the logic to invoke the native methods from JS and vice-versa. -### Fabric Components +### Fabric Native Components +<<<<<<< HEAD The content of each Fabric Component folder contains several files. The basic element for a Fabric Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore, it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. +||||||| parent of 1f97265d (Clarify New Architecture Terminology) +The content of each Fabric Component folder contains several files. The basic element for a Fabric Componenent is the `ShadowNode`: it represents a node in the React absract tree. The `ShadowNode` represents a React entity, therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. +======= +The content of each Fabric Native Component folder contains several files. The basic element for a Fabric Componenent is the `ShadowNode`: it represents a node in the React absract tree. The `ShadowNode` represents a React entity, therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. + +> > > > > > > 1f97265d (Clarify New Architecture Terminology) -Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. +Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Native Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. For further details about how Fabric works, have a look at the [Renderer](/architecture/fabric-renderer) section. ### RCTThirdPartyFabricComponentsProvider +<<<<<<< HEAD These are interface and implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Component. Once React Native has a handle to that class, it can instantiate it. +||||||| parent of 1f97265d (Clarify New Architecture Terminology) +These are an interface and an implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Component. Once React Native has an handle to that class, it can instantiate it. +======= +These are an interface and an implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Native Component. Once React Native has an handle to that class, it can instantiate it. + +> > > > > > > 1f97265d (Clarify New Architecture Terminology) # Android @@ -145,11 +166,18 @@ After that, you can navigate into the `SampleApp/android` folder and run: ./gradlew generateCodegenArtifactsFromSchema ``` +<<<<<<< HEAD These tasks invoke the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. +||||||| parent of 1f97265d (Clarify New Architecture Terminology) +This tasks invokes the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. +======= +This tasks invokes the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Native Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. + +> > > > > > > 1f97265d (Clarify New Architecture Terminology) ## The Generated Code -Once the Gradle task completes, you can see different structures for a TurboModule or for a Fabric Component. The following tab shows how they appear: +Once the Gradle task completes, you can see different structures for a Turbo Native Module or for a Fabric Native Component. The following tab shows how they appear: @@ -215,18 +243,32 @@ codegen Java can't interoperate seamlessly with C++ as Objective-C++ does. To work properly, **Codegen** creates some bridging between the Java and the C++ world in the `jni` folder, where the Java Native Interfaces are defined. +<<<<<<< HEAD Notice that both TurboModules and Fabric Components come with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. +||||||| parent of 1f97265d (Clarify New Architecture Terminology) +Notice that both TurboModules and Fabric Components comes with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. +======= +Notice that both Turbo Native Modules and Fabric Native Components comes with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. + +> > > > > > > 1f97265d (Clarify New Architecture Terminology) -### TurboModule +### Turbo Native Module The **Codegen** generates a Java abstract class in the `java` package with the same name as that of the TurboModule. This abstract class has to be implemented by the JNI C++ implementation. Then, it generates the C++ files in the `jni` folder. They follow the same iOS convention: there is an interface called `MyTurbomodule.h` and an implementation file called `MyTurbomodule-generated.cpp`. The former is an interface that allows React Native to initialize the JSI interface for the TurboModule. The latter is the implementation file which contains the logic to invoke the native method from JS and vice-versa. -### Fabric Component +### Fabric Native Component -The **Codegen** for a Fabric Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Component](./pillars-fabric-components) for details). +The **Codegen** for a Fabric Native Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Native Component](./pillars-fabric-components) for details). Then, there is a layer of JNI C++ files that are used by Fabric to render the components. The basic element for a Fabric Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. +<<<<<<< HEAD The **Codegen** also creates a `ComponentDescriptor.h`, which is required to get a proper handle on the Fabric Component. +||||||| parent of 1f97265d (Clarify New Architecture Terminology) +The **Codegen** also creates a `ComponentDescriptor.h` which is required to get a proper handle to the Fabric Component. +======= +The **Codegen** also creates a `ComponentDescriptor.h` which is required to get a proper handle to the Fabric Native Component. + +> > > > > > > 1f97265d (Clarify New Architecture Terminology) diff --git a/docs/the-new-architecture/pillars-fabric-components.md b/docs/the-new-architecture/pillars-fabric-components.md index fa9fd98321c..8b4af25fad4 100644 --- a/docs/the-new-architecture/pillars-fabric-components.md +++ b/docs/the-new-architecture/pillars-fabric-components.md @@ -1,6 +1,6 @@ --- id: pillars-fabric-components -title: Fabric Components +title: Fabric Native Components --- import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; @@ -9,24 +9,24 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; -A Fabric Component is a UI component rendered on the screen using the [Fabric Renderer](https://reactnative.dev/architecture/fabric-renderer). Using Fabric Components instead of Native Components allows us to reap all the [benefits](./why) of the **New Architecture**: +A Fabric Native Component is a Native Component rendered on the screen using the [Fabric Renderer](https://reactnative.dev/architecture/fabric-renderer). Using Fabric Native Components instead of Legacy Native Components allows us to reap all the [benefits](./why) of the **New Architecture**: - Strongly typed interfaces that are consistent across platforms. - The ability to write your code in C++, either exclusively or integrated with another native platform language, hence reducing the need to duplicate implementations across platforms. - The use of JSI, a JavaScript interface for native code, which allows for more efficient communication between native and JavaScript code than the bridge. -A Fabric Component is created starting from a **JavaScript specification**. Then [**Codegen**](./pillars-codegen) creates some C++ scaffolding code to connect the component-specific logic (for example, accessing some native platform capability) to the rest of the React Native infrastructure. The C++ code is the same for all the platforms. Once the component is properly connected with the scaffolding code, it is ready to be imported and used by an app. +A Fabric Native Component is created starting from a **JavaScript specification**. Then [**Codegen**](./pillars-codegen) creates some C++ scaffolding code to connect the component-specific logic (for example, accessing some native platform capability) to the rest of the React Native infrastructure. The C++ code is the same for all the platforms. Once the component is properly connected with the scaffolding code, it is ready to be imported and used by an app. -The following section guides you through the creation of a Fabric Component, step-by-step, targeting React Native 0.70.0. +The following section guides you through the creation of a Fabric Native Component, step-by-step, targeting React Native 0.70.0. :::caution -Fabric Components only works with the **New Architecture** enabled. +Fabric Native Components only works with the **New Architecture** enabled. To migrate to the **New Architecture**, follow the [Migration guide](../new-architecture-intro) ::: -## How to Create a Fabric Components +## How to Create a Fabric Native Components -To create a Fabric Component, you have to follow these steps: +To create a Fabric Native Component, you have to follow these steps: 1. Define a set of JavaScript specifications. 2. Configure the component so that **Codegen** can create the shared code and it can be added as a dependency for an app. @@ -36,9 +36,9 @@ Once these steps are done, the component is ready to be consumed by an app. The ## 1. Folder Setup -In order to keep the component decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Fabric Component that can be released as open-source libraries later. +In order to keep the component decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Fabric Native Component that can be released as open-source libraries later. -For this guide, you are going to create a Fabric Component that centers some text on the screen. +For this guide, you are going to create a Fabric Native Component that centers some text on the screen. Create a new folder at the same level of the app and call it `RTNCenteredText`. @@ -108,7 +108,7 @@ export default codegenNativeComponent( -At the beginning of the spec files, there are the imports. The most important imports, required by every Fabric Component are: +At the beginning of the spec files, there are the imports. The most important imports, required by every Fabric Native Component are: - The `HostComponent`: type the exported component needs to conform to. - The `codegenNativeComponent` function: responsible to actually register the component in the JavaScript runtime. @@ -119,7 +119,7 @@ Finally, the spec file exports the returned value of the `codegenNativeComponent :::caution The JavaScript files imports types from libraries, without setting up a proper node module and installing its dependencies. The outcome of this is that the IDE may have troubles resolving the import statements and it can output errors and warnings. -These will disappear as soon as the Fabric Component is added as a dependency of a React Native app. +These will disappear as soon as the Fabric Native Component is added as a dependency of a React Native app. ::: ## 3. Component Configuration @@ -136,7 +136,7 @@ The shared configuration is a `package.json` file that will be used by yarn when { "name": "rtn-centered-text", "version": "0.0.1", - "description": "Showcase a Fabric Component with a centered text", + "description": "Showcase a Fabric Native Component with a centered text", "react-native": "js/index", "source": "js/index", "files": [ @@ -178,7 +178,7 @@ Then there are the dependencies for this package. For this guide, you need `reac Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a Fabric Component, thus the value to use is `components`. +- `type`: The type of module contained by this package. In this case, it is a Fabric Native Component, thus the value to use is `components`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. ### iOS: Create the `.podspec` file @@ -350,7 +350,7 @@ The last step requires you to write some native code to connect the JavaScript s 1. Run **Codegen** to see what would be generated. 2. Write the native code that will make it work. -When developing a React Native app that uses a Fabric Component, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a Fabric Component as a library, it needs to reference the generated code, and it is useful to see what the app will generate. +When developing a React Native app that uses a Fabric Native Component, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a Fabric Component as a library, it needs to reference the generated code, and it is useful to see what the app will generate. As the first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](./pillars-codegen.md). @@ -456,11 +456,11 @@ RCT_EXPORT_VIEW_PROPERTY(text, NSString) @end ``` -This file is the manager for the Fabric Component. React Native runtime uses manager objects to register the modules, properties and methods to make them available to the JavaScript side. +This file is the manager for the Fabric Native Component. React Native runtime uses manager objects to register the modules, properties and methods to make them available to the JavaScript side. The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that Fabric can retrieve and instantiate it. -Then, you have to expose the `text` property for the Fabric Component. This is done with the `RCT_EXPORT_VIEW_PROPERTY` macro, specifying a name and a type. +Then, you have to expose the `text` property for the Fabric Native Component. This is done with the `RCT_EXPORT_VIEW_PROPERTY` macro, specifying a name and a type. :::info There are other macros that can be used to export custom properties, emitters, and other constructs. You can view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Views/RCTViewManager.h). @@ -567,7 +567,7 @@ The component has to conform to a specific protocol generated by **Codegen**, in Then, the file defines a static `(ComponentDescriptorProvider)componentDescriptorProvider` method which Fabric uses to retrieve the descriptor provider to instantiate the object. -Then, there is the constructor of the view: the `init` method. In this method, it is important to create a `defaultProps` struct using the `RTNCenteredTextProps` type from **Codegen**. You need to assign it to the private `_props` to initialize the Fabric Component correctly. The remaining part of the initializer is standard Objective-C code to create views and layout them with AutoLayout. +Then, there is the constructor of the view: the `init` method. In this method, it is important to create a `defaultProps` struct using the `RTNCenteredTextProps` type from **Codegen**. You need to assign it to the private `_props` to initialize the Fabric Native Component correctly. The remaining part of the initializer is standard Objective-C code to create views and layout them with AutoLayout. The last two pieces are the `updateProps` method and the `RTNCenteredTextCls` method. @@ -576,7 +576,7 @@ The `updateProps` method is invoked by Fabric every time a prop changes in JavaS Finally, the `RTNCenteredTextCls` is another static method used to retrieve the correct instance of the class at runtime. :::caution -Differently from Native Components, Fabric requires to manually implement the `updateProps` method. It's not enough to export properties with the `RCT_EXPORT_XXX` and `RCT_REMAP_XXX` macros. +Differently from Legacy Native Components, Fabric requires to manually implement the `updateProps` method. It's not enough to export properties with the `RCT_EXPORT_XXX` and `RCT_REMAP_XXX` macros. ::: ### Android @@ -630,13 +630,13 @@ codegen └── schema.json ``` -You can see that the content of the `codegen/jni/react/renderer/components/RTNCenteredTextSpecs` looks similar to the files created by the iOS counterpart. The `Android.mk` and `CMakeList.txt` files configure the Fabric Component in the app, while the `RTNCenteredTextManagerDelegate.java` and `RTNCenteredTextManagerInterface.java` files are meant use in your manager. +You can see that the content of the `codegen/jni/react/renderer/components/RTNCenteredTextSpecs` looks similar to the files created by the iOS counterpart. The `Android.mk` and `CMakeList.txt` files configure the Fabric Native Component in the app, while the `RTNCenteredTextManagerDelegate.java` and `RTNCenteredTextManagerInterface.java` files are meant use in your manager. See the [Codegen](./pillars-codegen) section for further details on the generated files. #### Write the Native Android Code -The native code for the Android side of a Fabric Components requires three pieces: +The native code for the Android side of a Fabric Native Components requires three pieces: 1. A `RTNCenteredText.java` that represents the actual view. 2. A `RTNCenteredTextManager.java` to instantiate the view. @@ -788,11 +788,11 @@ public class RTNCenteredTextPackage implements ReactPackage { } ``` -The added lines instantiate a new `RTNCenteredTextManager` object so that the React Native runtime can use it to render our Fabric Component. +The added lines instantiate a new `RTNCenteredTextManager` object so that the React Native runtime can use it to render our Fabric Native Component. -## 5. Adding the Fabric Component To Your App +## 5. Adding the Fabric Native Component To Your App -This is the last step to finally see your Fabric Component running on your app. +This is the last step to finally see your Fabric Native Component running on your app. ### Shared diff --git a/docs/the-new-architecture/pillars-turbomodule.md b/docs/the-new-architecture/pillars-turbomodule.md index 9452acaf086..29f8c2a775a 100644 --- a/docs/the-new-architecture/pillars-turbomodule.md +++ b/docs/the-new-architecture/pillars-turbomodule.md @@ -1,6 +1,6 @@ --- id: pillars-turbomodules -title: TurboModules +title: Turbo Native Modules --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; @@ -10,23 +10,23 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; If you've worked with React Native, you may be familiar with the concept of [Native Modules](../native-modules-intro.md), which allow JavaScript and platform-native code to communicate over the React Native "bridge", which handles cross-platform serialization via JSON. -TurboModules are the next iteration on Native Modules that provide a few extra [benefits](./why): +Turbo Native Modules are the next iteration on Native Modules that provide a few extra [benefits](./why): - Strongly typed interfaces that are consistent across platforms - The ability to write your code in C++, either exclusively or integrated with another native platform language, reducing the need to duplicate implementations across platforms - Lazy loading of modules, allowing for faster app startup - The use of JSI, a JavaScript interface for native code, allows for more efficient communication between native and JavaScript code than the bridge -This guide will show you how to create a basic TurboModule compatible with React Native 0.70.0. +This guide will show you how to create a basic Turbo Native Module compatible with React Native 0.70.0. :::caution -TurboModules only work with the **New Architecture** enabled. +Turbo Native Modules only work with the **New Architecture** enabled. To migrate to the **New Architecture**, follow the [Migration guide](../new-architecture-intro) ::: -## How to Create a TurboModule +## How to Create a Turbo Native Module -To create a TurboModule, we need to: +To create a Turbo Native Module, we need to: 1. Define the JavaScript specification. 2. Configure the module so that Codegen can generate the scaffolding. @@ -34,7 +34,7 @@ To create a TurboModule, we need to: ## 1. Folder Setup -In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing TurboModules that can be released as open-source libraries later. +In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Turbo Native Modules that can be released as open-source libraries later. Next to your application, create a folder called `RTNCalculator`. **RTN** stands for "**R**eac**t** **N**ative", and is a recommended prefix for React Native modules. @@ -97,12 +97,12 @@ export default TurboModuleRegistry.get( At the beginning of the spec files are the imports: -- The `TurboModule` type, which defines the base interface for all TurboModules -- The `TurboModuleRegistry` JavaScript module, which contains functions for loading TurboModules +- The `TurboModule` type, which defines the base interface for all Turbo Native Modules +- The `TurboModuleRegistry` JavaScript module, which contains functions for loading Turbo Native Modules -The second section of the file contains the interface specification for the TurboModule. In this case, the interface defines the `add` function, which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a TurboModule. +The second section of the file contains the interface specification for the Turbo Native Module. In this case, the interface defines the `add` function, which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a Turbo Native Module. -Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the TurboModule if it's available. +Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the Turbo Native Module if it's available. :::caution We are writing JavaScript files importing types from libraries, without setting up a proper node module and installing its dependencies. Your IDE will not be able to resolve the import statements and you may see errors and warnings. This is expected and will not cause problems when you add the module to your app. @@ -122,7 +122,7 @@ The shared configuration is a `package.json` file used by yarn when installing y { "name": "rtn-calculator", "version": "0.0.1", - "description": "Add numbers with TurboModules", + "description": "Add numbers with Turbo Native Modules", "react-native": "js/index", "source": "js/index", "files": [ @@ -167,7 +167,7 @@ Then there are the dependencies for this package. For this guide, you need `reac Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a TurboModule; thus, the value to use is `modules`. +- `type`: The type of module contained by this package. In this case, it is a Turbo Native Module; thus, the value to use is `modules`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. - `android.javaPackageName`: the package to use in the Java files generated by **Codegen**. @@ -329,12 +329,12 @@ React Native uses the `ReactPackage` interface to understand what native classes ## 4. Native Code -For the final step in getting your TurboModule ready to go, you'll need to write some native code to connect the JavaScript side to the native platforms. This process requires two main steps: +For the final step in getting your Turbo Native Module ready to go, you'll need to write some native code to connect the JavaScript side to the native platforms. This process requires two main steps: - Run **Codegen** to see what it generates. - Write your native code, implementing the generated interfaces. -When developing a React Native app that uses a TurboModule, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore, useful to see what the app will generate. +When developing a React Native app that uses a Turbo Native Module, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore, useful to see what the app will generate. As the first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](pillars-codegen.md). @@ -390,7 +390,7 @@ generated └── ShadowNodes.h ``` -The relevant path for the TurboModule interface is `generated/build/generated/ios/RTNCalculatorSpec`. +The relevant path for the Turbo Native Module interface is `generated/build/generated/ios/RTNCalculatorSpec`. See the [Codegen](./pillars-codegen) section for further details on the generated files. @@ -407,7 +407,7 @@ rm -rf build #### Write the Native iOS Code -Now add the Native code for your TurboModule. Create two files in the `RTNCalculator/ios` folder: +Now add the Native code for your Turbo Native Module. Create two files in the `RTNCalculator/ios` folder: 1. The `RTNCalculator.h`, a header file for the module. 2. The `RTNCalculator.mm`, the implementation of the module. @@ -456,11 +456,11 @@ RCT_REMAP_METHOD(add, addA:(NSInteger)a @end ``` -The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that React Native can load the TurboModule. +The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that React Native can load the Turbo Native Module. Then the `RCT_REMAP_METHOD` macro is used to expose the `add` method. -Finally, the `getTurboModule` method gets an instance of the TurboModule so that the JavaScript side can invoke its methods. The function is defined in (and requested by) the `RTNCalculatorSpec.h` file that was generated earlier by Codegen. +Finally, the `getTurboModule` method gets an instance of the Turbo Native Module so that the JavaScript side can invoke its methods. The function is defined in (and requested by) the `RTNCalculatorSpec.h` file that was generated earlier by Codegen. :::info There are other macros that can be used to export modules and methods. You view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Base/RCTBridgeModule.h). @@ -516,7 +516,7 @@ codegen #### Write the Native Android Code -The native code for the Android side of a TurboModule requires: +The native code for the Android side of a Turbo Native Module requires: 1. to create a `RTNCalculatorModule.java` that implements the module. 2. to update the `RTNCalculatorPackage.java` created in the previous step. @@ -628,9 +628,9 @@ public class CalculatorPackage extends TurboReactPackage { This is the last piece of Native Code for Android. It defines the `TurboReactPackage` object that will be used by the app to load the module. -## 5. Adding the TurboModule to your App +## 5. Adding the Turbo Native Module to your App -Now you can install and use the TurboModule in your app. +Now you can install and use the Turbo Native Module in your app. ### Shared @@ -667,7 +667,7 @@ Android configuration requires to enable the **New Architecture**: ### JavaScript -Now you can use your TurboModule calculator in your app! +Now you can use your Turbo Native Module calculator in your app! Here's an example App.js file using the `add` method: @@ -711,4 +711,4 @@ const App: () => Node = () => { export default App; ``` -Try this out to see your TurboModule in action! +Try this out to see your Turbo Native Module in action! diff --git a/docs/the-new-architecture/pillars.md b/docs/the-new-architecture/pillars.md index 05a828af51c..14fd75eb8cf 100644 --- a/docs/the-new-architecture/pillars.md +++ b/docs/the-new-architecture/pillars.md @@ -9,12 +9,19 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; The New Architecture is composed mainly of two pillars: -- [TurboModules](pillars-turbomodules) -- [Fabric Components](pillars-fabric-components). +- [The New Native Module System - Turbo Modules](pillars-turbomodules) +- [The New Renderer - Fabric](pillars-fabric-components). -TurboModules are the preferred way to create libraries that leverage some platform-specific API. Fabric Components are the preferred way to create reusable UI components, providing a native experience to the users. +The core concepts of React Native still holds true in the New Architecture: Native Modules are the preferred way to create libraries that leverage some platform-specific API. Native Components are the preferred way to create reusable UI components, providing a native experience to the users. -The main goal of this section is to drive the reader through a step-by-step guide to create their first TurboModule or Fabric Component. +The main goal of this section is to drive the reader through a step-by-step guide to create their first Native Module or Component which is compatible with the New Architecture. + +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Components** & **Legacy Native Modules** - To refer to Modules and Components which are running on the old React Native architecture. +- **Fabric Native Components** & **Turbo Native Modules** - To refer to Modules and Components which have been adapted to work well with the New Architecture, namely the new renderer and the new Native Module System. For brevity you might find them referred as **Fabric Components** and **Turbo Modules** + ::: The next sections contain a high-level overview of the pillars and the steps to create them. To create one of these pillars, the steps are: @@ -26,7 +33,7 @@ The next sections contain a high-level overview of the pillars and the steps to Finally, we dive a little deeper into the [Codegen](pillars-codegen) process that is required to create all the C++ types and files used by our components, including some useful steps to work comfortably while developing the component. :::caution -The app has to run with the **New Architecture enabled to integrate a TurboModule or a Fabric Component** in an app. +The app has to run with the **New Architecture enabled to integrate a Turbo Native Module or a Fabric Native Component** in an app. To create a new app adopting the New Architecture, refer to the [Using the App Template](use-app-template) section. To migrate an existing app to the New Architecture, refer to the [Migration](../new-architecture-intro) guide. diff --git a/docs/the-new-architecture/use-app-template.md b/docs/the-new-architecture/use-app-template.md index 8abd06fb9a8..53f96acc3f6 100644 --- a/docs/the-new-architecture/use-app-template.md +++ b/docs/the-new-architecture/use-app-template.md @@ -123,8 +123,8 @@ For further explanations of what each file is doing, check out these guides to w #### Android -- [Enabling TurboModules on Android](new-architecture-app-modules-android.md) -- [Enabling Fabric on Android](new-architecture-app-renderer-android.md) +- [Enabling the New Native Module System (Turbo Module) on Android](new-architecture-app-modules-android.md) +- [Enabling the New Renderer (Fabric) on Android](new-architecture-app-renderer-android.md) #### iOS diff --git a/docs/the-new-architecture/why.md b/docs/the-new-architecture/why.md index 84b8fe62e0e..964cfb0e9ef 100644 --- a/docs/the-new-architecture/why.md +++ b/docs/the-new-architecture/why.md @@ -35,7 +35,7 @@ This idea allowed the unlocking of several benefits: - **Code sharing:** by introducing C++, it is now possible to abstract all the platform agnostic code and to share it with ease between the platforms. - **Type safety:** to make sure that JS can properly invoke methods on C++ objects and vice-versa, a layer of code automatically generated has been added. The code is generated starting from some JS specification that must be typed through Flow or TypeScript. -These advantages are the foundations of the [TurboModule](pillars-turbomodules) system and a jumping stone to further enhancements. For example, it has been possible to develop a new renderer that is faster and more performant: [Fabric](/architecture/fabric-renderer) and its [Fabric Components](pillars-fabric-components). +These advantages are the foundations of the [New Native Module System](pillars-turbomodules) and a jumping stone to further enhancements. For example, it has been possible to develop a [new renderer](/architecture/fabric-renderer) which offers faster and more performant [Native Components](pillars-fabric-components). ## Further Reading From 63d00e7b4e91545c16fe8c505f9ed9b24ac82b73 Mon Sep 17 00:00:00 2001 From: Ricky Date: Fri, 9 Sep 2022 15:13:35 -0400 Subject: [PATCH 18/88] Revert "Clarify New Architecture Terminology (#3308)" (#3314) This reverts commit 54d266b7842e1dda86b5877466f6a61fcf5bf043. --- docs/new-architecture-app-intro.md | 2 +- docs/new-architecture-app-modules-android.md | 10 +-- docs/new-architecture-app-renderer-android.md | 2 +- docs/new-architecture-appendix.md | 17 ++--- docs/new-architecture-intro.md | 4 +- docs/new-architecture-library-intro.md | 6 +- docs/new-architecture-library-ios.md | 2 +- docs/react-18-and-react-native.md | 2 +- .../_markdown_native_deprecation.mdx | 2 +- ...ackward-compatibility-fabric-components.md | 47 ++++++------ .../backward-compatibility-turbomodules.md | 45 +++++------- .../backward-compatibility.md | 6 +- docs/the-new-architecture/landing-page.md | 6 +- docs/the-new-architecture/pillars-codegen.md | 72 ++++--------------- .../pillars-fabric-components.md | 46 ++++++------ .../pillars-turbomodule.md | 48 ++++++------- docs/the-new-architecture/pillars.md | 17 ++--- docs/the-new-architecture/use-app-template.md | 4 +- docs/the-new-architecture/why.md | 2 +- 19 files changed, 134 insertions(+), 206 deletions(-) diff --git a/docs/new-architecture-app-intro.md b/docs/new-architecture-app-intro.md index c0d56f91a71..2b1de555728 100644 --- a/docs/new-architecture-app-intro.md +++ b/docs/new-architecture-app-intro.md @@ -188,7 +188,7 @@ React Native also supports a local version of this file `.xcode.env.local`. This ## iOS - Use Objective-C++ (`.mm` extension) -Turbo Native Modules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. +TurboModules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. :::important diff --git a/docs/new-architecture-app-modules-android.md b/docs/new-architecture-app-modules-android.md index 02069ffac51..b3e8fddfb7c 100644 --- a/docs/new-architecture-app-modules-android.md +++ b/docs/new-architecture-app-modules-android.md @@ -100,7 +100,7 @@ yarn react-native run-android ## 2. Java/Kotlin - Provide a `ReactPackageTurboModuleManagerDelegate` -Now is time to actually use the Turbo Native Module. +Now is time to actually use the TurboModule. First, we will need to create a `ReactPackageTurboModuleManagerDelegate` subclass, like the following: @@ -193,7 +193,7 @@ protected constructor( Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `project()` inside the `CMakeLists.txt` file you created before. -This class will then be responsible of loading the Turbo Native Modules and will take care of loading the native library build with the NDK at runtime. +This class will then be responsible of loading the TurboModules and will take care of loading the native library build with the NDK at runtime. ## 3. Adapt your `ReactNativeHost` to use the `ReactPackageTurboModuleManagerDelegate` @@ -259,7 +259,7 @@ class MyApplication : Application(), ReactApplication { ## 4. Extend the `getPackages()` from your `ReactNativeHost` to use the TurboModule -Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created Turbo Native Module. Update the method to include the following: +Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created TurboModule. Update the method to include the following: @@ -493,7 +493,7 @@ std::shared_ptr MyApplicationModuleProvider(const std::string modul Please adapt the `samplelibrary.h` import to match the same library name you provided when building the apps. This is the C++ generated file that is created by the codegen. -Here you can also specify more than one provider, should you have more than one Turbo Native Module. Specifically in this example we look for a Turbo Native Module from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). +Here you can also specify more than one provider, should you have more than one TurboModule. Specifically in this example we look for a TurboModule from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). ```cpp #include "MyApplicationModuleProvider.h" @@ -532,7 +532,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { ## 6. Enable the `useTurboModules` flag in your Application `onCreate` -Now you can finally enable the `Turbo Native Module` support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. +Now you can finally enable the `TurboModule `support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. diff --git a/docs/new-architecture-app-renderer-android.md b/docs/new-architecture-app-renderer-android.md index 39bb732efbf..736abcb8f56 100644 --- a/docs/new-architecture-app-renderer-android.md +++ b/docs/new-architecture-app-renderer-android.md @@ -113,7 +113,7 @@ LOG Running "App" with {"fabric":true,"initialProps":{},"rootTag":1} ## Migrating Android ViewManagers -First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (Turbo Module) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. +First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. ### JavaScript changes diff --git a/docs/new-architecture-appendix.md b/docs/new-architecture-appendix.md index 61bbc1377e3..56b3301423b 100644 --- a/docs/new-architecture-appendix.md +++ b/docs/new-architecture-appendix.md @@ -7,16 +7,7 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; -## I. Terminology - -The whole New Architecture related guides will stick to the following **terminology**: - -- **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. -- **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. -- **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Architecture, namely the new renderer. For brevity you might find them referred as **Fabric Components**. -- **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Architecture, namely the new Native Module System. For brevity you might find them referred as **Turbo Modules** - -## II. Flow Type to Native Type Mapping +## I. Flow Type to Native Type Mapping You may use the following table as a reference for which types are supported and what they map to in each platform: @@ -94,7 +85,7 @@ Callback functions are not type checked, and are generalized as `Object`s. You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository. ::: -## III. TypeScript to Native Type Mapping +## II. TypeScript to Native Type Mapping You may use the following table as a reference for which types are supported and what they map to in each platform: @@ -114,7 +105,7 @@ You may use the following table as a reference for which types are supported and You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository. -## IV. Invoking the code-gen during development +## III. Invoking the code-gen during development > This section contains information specific to v0.66 of React Native. @@ -191,7 +182,7 @@ node node_modules/react-native/scripts/generate-specs-cli.js \ In the above example, the code-gen script will generate several files: `MyLibSpecs.h` and `MyLibSpecs-generated.mm`, as well as a handful of `.h` and `.cpp` files, all located in the `ios` directory. -## V. Note on Existing Apps +## IV. Note on Existing Apps This guide provides instructions for migrating an application that is based on the default app template that is provided by React Native. If your app has deviated from the template, or you are working with an application that was never based off the template, then the following sections might help. diff --git a/docs/new-architecture-intro.md b/docs/new-architecture-intro.md index e5b224a1649..fce2e38630b 100644 --- a/docs/new-architecture-intro.md +++ b/docs/new-architecture-intro.md @@ -9,7 +9,7 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; # Getting Started with the New Architecture -This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **New Native Module system (Turbo Module) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps. +This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **new NativeModule system (TurboModule) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps. ## Table of Contents @@ -23,7 +23,7 @@ The guide is divided into five sections: - **Supporting the New Architecture in your App** - [Prerequisites for Supporting the New Architecture in your App](new-architecture-app-intro) - Android - - [Enabling the New Native Module System (Turbo Module) in your App](new-architecture-app-modules-android) + - [Enabling the New NativeModule System (TurboModule) in your App](new-architecture-app-modules-android) - [Enabling the New Renderer (Fabric) in your App](new-architecture-app-renderer-android) - [**React 18 & React Native**](react-18-and-react-native) - [**Troubleshooting**](new-architecture-troubleshooting) diff --git a/docs/new-architecture-library-intro.md b/docs/new-architecture-library-intro.md index 0d905261fb7..9d688a8151e 100644 --- a/docs/new-architecture-library-intro.md +++ b/docs/new-architecture-library-intro.md @@ -23,7 +23,7 @@ Currently, this guide is written under the assumption that you will be using [Fl To adopt the New Architecture, you start by creating these specs for your native modules and native components. You can do this prior to actually migrating to the New Architecture: the specs will be used later on to generate native interface code for all the supported platforms as a way to enforce uniform APIs across platforms. -#### Turbo Native Modules +#### Turbomodules JavaScript spec files **must** be named `Native.js` and they export a `TurboModuleRegistry` `Spec` object. The name convention is important because the Codegen process looks for modules whose `js` (`jsx`, `ts`, or `tsx`) spec file starts with the keyword `Native`. @@ -70,7 +70,7 @@ export default TurboModuleRegistry.get(''); -#### Fabric Native Components +#### Fabric Components JavaScript spec files **must** be named `NativeComponent.js` (for TypeScript use extension `.ts` or `.tsx`) and they export a `HostComponent` object. The name convention is important: the Codegen process looks for components whose spec file (either JavaScript or TypeScript) ends with the suffix `NativeComponent`. @@ -214,7 +214,7 @@ Codegen can be configured in the `package.json` file of your Library. Add the fo - The `codegenConfig` is the key used by the Codegen to verify that there is some code to generate. - The `name` field is the name of the library. -- The `type` field is used to identify the type of module we want to create. Our suggestion is to keep `all` to support libraries that contain both Turbo Native Module and Fabric Native Components. +- The `type` field is used to identify the type of module we want to create. Our suggestion is to keep `all` to support libraries that contain both TurboModule and Fabric Components. - The `jsSrcsDir` is the directory where the codegen will start looking for JavaScript specs. - The `android.javaPackageName` is the name of the package where the generated code wil end up. diff --git a/docs/new-architecture-library-ios.md b/docs/new-architecture-library-ios.md index 1fb8eee0851..8eca9aa3184 100644 --- a/docs/new-architecture-library-ios.md +++ b/docs/new-architecture-library-ios.md @@ -32,7 +32,7 @@ Pod::Spec.new do |s| } s.dependency "React-Core" - s.dependency "React-RCTFabric" # This is for Fabric Native Component + s.dependency "React-RCTFabric" # This is for Fabric Component s.dependency "React-Codegen" s.dependency "RCT-Folly" s.dependency "RCTRequired" diff --git a/docs/react-18-and-react-native.md b/docs/react-18-and-react-native.md index 33892b9e1d6..ed4a5d09eb6 100644 --- a/docs/react-18-and-react-native.md +++ b/docs/react-18-and-react-native.md @@ -31,7 +31,7 @@ The concurrent features in React 18 are built on top of the new concurrent rende Previous versions of React Native built on the old architecture **cannot** support concurrent rendering or concurrent features. This is because the old architecture relied on mutating the native trees, which doesn’t allow for React to prepare multiple versions of the tree at the same time. -Fortunately, the New Architecture was written bottom-up with concurrent rendering in mind, and is fully compatible with React 18. This means, in order to upgrade to React 18 in your React Native app, your application needs to be migrated to the React Native's New Architecture including Fabric Native Components and Turbo Native Modules. +Fortunately, the New Architecture was written bottom-up with concurrent rendering in mind, and is fully compatible with React 18. This means, in order to upgrade to React 18 in your React Native app, your application needs to be migrated to the React Native's New Architecture including Fabric and TurboModules. ## React 18 enabled by default diff --git a/docs/the-new-architecture/_markdown_native_deprecation.mdx b/docs/the-new-architecture/_markdown_native_deprecation.mdx index 390bfcdc3de..569a078d147 100644 --- a/docs/the-new-architecture/_markdown_native_deprecation.mdx +++ b/docs/the-new-architecture/_markdown_native_deprecation.mdx @@ -1,4 +1,4 @@ :::info Native Module and Native Components are our stable technologies used by the legacy architecture. -They will be deprecated in the future when the New Architecture will be stable. The New Architecture uses [Turbo Native Module](./the-new-architecture/pillars-turbomodules) and [Fabric Native Components](./the-new-architecture/pillars-fabric-components) to achieve similar results. +They will be deprecated in the future when the New Architecture will be stable. The New Architecture uses [TurboModule](./the-new-architecture/pillars-turbomodules) and [Fabric Components](./the-new-architecture/pillars-fabric-components) to achieve similar results. ::: diff --git a/docs/the-new-architecture/backward-compatibility-fabric-components.md b/docs/the-new-architecture/backward-compatibility-fabric-components.md index 8f67e7dcc1d..64f93c1834f 100644 --- a/docs/the-new-architecture/backward-compatibility-fabric-components.md +++ b/docs/the-new-architecture/backward-compatibility-fabric-components.md @@ -1,6 +1,6 @@ --- id: backward-compatibility-fabric-components -title: Fabric Components as Legacy Native Components +title: Fabric Components as Native Components --- import Tabs from '@theme/Tabs'; @@ -12,35 +12,28 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -Creating a backward compatible Fabric Native Component requires the knowledge of how to create a Legacy Native Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). +Creating a backward compatible Fabric Component requires the knowledge of how to create a Fabric Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). -Fabric Native Components only work when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. +Fabric Components only work when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: -Creating a backward compatible Fabric Native Component lets your users continue to leverage your library independently from the architecture they use. The creation of such a component requires a few steps: +Creating a backward compatible Fabric Component lets your users continue to leverage your library independently from the architecture they use. The creation of such a component requires a few steps: 1. Configure the library so that dependencies are prepared to set up properly for both the Old and the New Architecture. 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. -:::info -For the sake of this guide we're going to use the following **terminology**: - -- **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. -- **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Native Renderer, Fabric. For brevity you might find them referred as **Fabric Components**. - ::: - While the last step is the same for all the platforms, the first two steps are different for iOS and Android. -## Configure the Fabric Native Component Dependencies +## Configure the Fabric Component Dependencies ### iOS -The Apple platform installs Fabric Native Components using [Cocoapods](https://cocoapods.org) as a dependency manager. +The Apple platform installs Fabric Components using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every Fabric Native Component defines a `podspec` that looks like this: +Every Fabric Component defines a `podspec` that looks like this: ```ruby require "json" @@ -111,13 +104,13 @@ This `if` guard prevents the dependencies from being installed when the environm ### Android -To create a Native Component that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. +To create a module that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. :::note Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: -To configure the Fabric Native Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: +To configure the Fabric Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: ```diff title="build.gradle" +// Add this function in case you don't have it already @@ -155,7 +148,7 @@ These changes do three main things: The second step is to instruct Xcode to avoid compiling all the lines using the New Architecture types and files when we are building an app with the Old Architecture. -A Fabric Native Component requires an header file and an implementation file to add the actual `View` to the module. +A Fabric Component requires an header file and an implementation file to add the actual `View` to the module. For example, the `RNMyComponentView.h` header file could look like this: @@ -243,15 +236,15 @@ As we can't use conditional compilation blocks on Android, we will define two di Therefore, you have to: -1. Create a Legacy Native Component in the `src/oldarch` path. See [this guide](../native-components-android) to learn how to create a Legacy Native Component. -2. Create a Fabric Native Component in the `src/newarch` path. See [this guide](pillars-fabric-components) to learn how to create a Fabric Native Component. +1. Create a Native Component in the `src/oldarch` path. See [this guide](../native-components-android) to learn how to create a Native Component. +2. Create a Fabric Component in the `src/newarch` path. See [this guide](pillars-fabric-components) to learn how to create a Fabric Component. and then instruct Gradle to decide which implementation to pick. -Some files can be shared between a Legacy and a Fabric Component: these should be created or moved into a folder that is loaded by both the architectures. These files are: +Some files can be shared between a Native and a Fabric Component: these should be created or moved into a folder that is loaded by both the architectures. These files are: - the `.java` that instantiate and configure the Android View for both the components. -- the `ManagerImpl.java` file where which contains the logic of the ViewManager that can be shared between the Legacy and the Fabric Component. +- the `ManagerImpl.java` file where which contains the logic of the ViewManager that can be shared between the Native and the Fabric Component. - the `Package.java` file used to load the component. The final folder structure looks like this: @@ -282,7 +275,7 @@ my-component └── package.json ``` -The code that should go in the `MyComponentViewManagerImpl.java` and that can be shared between the Native Component and the Fabric Native Component is, for example: +The code that should go in the `MyComponentViewManagerImpl.java` and that can be shared between the Native Component and the Fabric Component is, for example: ```java title="example of MyComponentViewManager.java" package com.MyComponent; @@ -303,7 +296,7 @@ public class MyComponentViewManagerImpl { } ``` -Then, the Native Component and the Fabric Native Component can be updated using the function declared in the shared manager. +Then, the Native Component and the Fabric Component can be updated using the function declared in the shared manager. For example, for a Native Component: @@ -337,7 +330,7 @@ public class MyComponentViewManager extends SimpleViewManager { } ``` -And, for a Fabric Native Component: +And, for a Fabric Component: ```java title="Fabric Component using the ViewManagerImpl" // Use the static NAME property from the shared implementation @@ -388,7 +381,7 @@ For a step-by-step example on how to achieve this, have a look at [this repo](ht The last step makes sure that the JavaScript behaves transparently to chosen architecture. -For a Fabric Native Component, the source of truth is the `NativeComponent.js` (or `.ts`) spec file. The app accesses the spec file like this: +For a Fabric Component, the source of truth is the `NativeComponent.js` (or `.ts`) spec file. The app accesses the spec file like this: ```ts import MyComponent from 'your-component/src/index'; @@ -438,5 +431,5 @@ Whether you are using Flow or TypeScript for your specs, we understand which arc Please note that the New Architecture is still experimental. The `global.nativeFabricUIManager` API might change in the future for a function that encapsulate this check. ::: -- If that object is `null`, then the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Legacy Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). -- If that object is set, the app is running with Fabric enabled, and it should use the `NativeComponent` spec to access the Fabric Native Component. +- If that object is `null`, then the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). +- If that object is set, the app is running with Fabric enabled, and it should use the `NativeComponent` spec to access the Fabric Component. diff --git a/docs/the-new-architecture/backward-compatibility-turbomodules.md b/docs/the-new-architecture/backward-compatibility-turbomodules.md index 590220e6453..9b636d4fb79 100644 --- a/docs/the-new-architecture/backward-compatibility-turbomodules.md +++ b/docs/the-new-architecture/backward-compatibility-turbomodules.md @@ -1,6 +1,6 @@ --- id: backward-compatibility-turbomodules -title: Turbo Modules as Legacy Native Modules +title: TurboModules as Native Modules --- import Tabs from '@theme/Tabs'; @@ -12,7 +12,7 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -Creating a backward compatible Turbo Native Module requires the knowledge of how to create a Legacy Native Module. To recall these concepts, have a look at this [guide](pillars-turbomodules). +Creating a backward compatible TurboModule requires the knowledge of how to create a TurboModule. To recall these concepts, have a look at this [guide](pillars-turbomodules). TurboModules only works when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: @@ -23,24 +23,17 @@ Creating a backward compatible TurboModule lets your users continue to leverage 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. -:::info -For the sake of this guide we're going to use the following **terminology**: - -- **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. -- **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Native Module System. For brevity you might find them referred as **Turbo Modules**. - ::: - While the last step is the same for all the platforms, the first two steps are different for iOS and Android. -## Configure the Turbo Native Module Dependencies +## Configure the TurboModule Dependencies ### iOS -The Apple platform installs Turbo Native Modules using [Cocoapods](https://cocoapods.org) as a dependency manager. +The Apple platform installs TurboModules using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every Turbo Native Module defines a `podspec` that looks like this: +Every TurboModule defines a `podspec` that looks like this: ```ruby require "json" @@ -116,7 +109,7 @@ To create a module that can work with both architectures, you need to configure Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure the maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: -To configure the Turbo Native Module so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: +To configure the TurboModule so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: ```diff title="build.gradle" +// Add this function in case you don't have it already @@ -163,7 +156,7 @@ The file to change is the module implementation file, which is usually a `` type, generated by The New Architecture. -The **goal** is to make sure that the `Turbo Native Module` still builds with the Old Architecture. To achieve that, we can wrap the `#import ".h"` and the `getTurboModule:` function into an `#ifdef RCT_NEW_ARCH_ENABLED` compilation directive, as shown in the following example: +The **goal** is to make sure that the `TurboModule` still builds with the Old Architecture. To achieve that, we can wrap the `#import ".h"` and the `getTurboModule:` function into an `#ifdef RCT_NEW_ARCH_ENABLED` compilation directive, as shown in the following example: ```diff #import ".h" @@ -188,19 +181,19 @@ This snippet uses the same `RCT_NEW_ARCH_ENABLED` flag used in the previous [sec ### Android -As we can't use conditional compilation blocks on Android, we will define two different source sets. This will allow to create a backward compatible Turbo Native Module with the proper source that is loaded and compiled depending on the used architecture. +As we can't use conditional compilation blocks on Android, we will define two different source sets. This will allow to create a backward compatible TurboModule with the proper source that is loaded and compiled depending on the used architecture. Therefore, you have to: -1. Create a Legacy Native Module in the `src/oldarch` path. See [this guide](../native-modules-intro) to learn how to create a Legacy Native Module. -2. Create a Turbo Native Module in the `src/newarch` path. See [this guide](./pillars-turbomodules) to learn how to create a Turbo Native Module +1. Create a Native Module in the `src/oldarch` path. See [this guide](../native-modules-intro) to learn how to create a Native Module. +2. Create a TurboModule in the `src/newarch` path. See [this guide](./pillars-turbomodules) to learn how to create a TurboModule and then instruct Gradle to decide which implementation to pick. -Some files can be shared between a Legacy Native Module and a Turbo Native Module: these should be created or moved into a folder that is loaded by both the architectures. These files are: +Some files can be shared between a Native Module and a TurboModule: these should be created or moved into a folder that is loaded by both the architectures. These files are: - the `Package.java` file used to load the module. -- a `Impl.java` file where we can put the code that both the Legacy Native Module and the Turbo Native Module has to execute. +- a `Impl.java` file where we can put the code that both the Native Module and the TurboModule has to execute. The final folder structure looks like this: @@ -229,7 +222,7 @@ my-module └── package.json ``` -The code that should go in the `MyModuleImpl.java`, and that can be shared by the Legacy Native Module and the Turbo Native Module is, for example: +The code that should go in the `MyModuleImpl.java`, and that can be shared by the Native Module and the TurboModule is, for example: ```java title="example of MyModuleImple.java" package com.MyModule; @@ -250,13 +243,13 @@ public class MyModuleImpl { } ``` -Then, the Legacy Native Module and the Turbo Native Module can be updated with the following steps: +Then, the Native Module and the TurboModule can be updated with the following steps: 1. Create a private instance of the `MyModuleImpl` class. 2. Initialize the instance in the module constructor. 3. Use the private instance in the modules methods. -For example, for a Legacy Native Module: +For example, for a Native Module: ```java title="Native Module using the Impl module" public class MyModule extends ReactContextBaseJavaModule { @@ -284,7 +277,7 @@ public class MyModule extends ReactContextBaseJavaModule { } ``` -And, for a Turbo Native Module: +And, for a TurboModule: ```java title="TurboModule using the Impl module" public class MyModule extends MyModuleSpec { @@ -320,7 +313,7 @@ For a step-by-step example on how to achieve this, have a look at [this repo](ht The last step makes sure that the JavaScript behaves transparently to chosen architecture. -For a Turbo Native Module, the source of truth is the `Native.js` (or `.ts`) spec file. The app accesses the spec file like this: +For a TurboModule, the source of truth is the `Native.js` (or `.ts`) spec file. The app accesses the spec file like this: ```ts import MyModule from 'your-module/src/index'; @@ -373,5 +366,5 @@ Whether you are using Flow or TypeScript for your specs, we understand which arc The `global.__turboModuleProxy` API may change in the future for a function that encapsulates this check. ::: -- If that object is `null`, the app has not enabled the Turbo Native Module feature. It's running on the Old Architecture, and the fallback is to use the default [`Legacy Native Module` implementation](../native-modules-intro). -- If that object is set, the app is running with the Turbo Native Modules enabled, and it should use the `Native` spec to access the Turbo Native Module. +- If that object is `null`, the app has not enabled the TurboModule feature. It's running on the Old Architecture, and the fallback is to use the default [`NativeModule` implementation](../native-modules-intro). +- If that object is set, the app is running with the TurboModules enabled, and it should use the `Native` spec to access the TurboModule. diff --git a/docs/the-new-architecture/backward-compatibility.md b/docs/the-new-architecture/backward-compatibility.md index babe5507485..89c1f3ac73f 100644 --- a/docs/the-new-architecture/backward-compatibility.md +++ b/docs/the-new-architecture/backward-compatibility.md @@ -11,7 +11,7 @@ Creating a backward compatible module is important to provide a library that wor The trick to create a good backward compatible module is to minimize the changes required to adopt the new version. In that way, users of the module can smoothly move to the new version and migrate to the New Architecture when they are ready, ideally by issueing one different command. -To achieve this result, we have to perform few changes in our **Turbo Native Module** and **Fabric Native Component** configurations. The steps we have to follow are: +To achieve this result, we have to perform few changes in our **TurboModule** and **Fabric Component** configurations. The steps we have to follow are: 1. **Update the installation configuration** to avoid using code that is not needed by the Old Architecture. 1. **Update the code** to support both architectures. Both Android and iOS build pipelines gives you mechanism to provide a library that will compile with the correct React Native Architecture. @@ -21,5 +21,5 @@ To achieve this result, we have to perform few changes in our **Turbo Native Mod The next sections requires that you are familiar with the [Pillars](pillars) of the **New Architecture**. ::: -- To create a backward compatible **Turbo Native Module**, follow [this guide](backward-compatibility-turbomodules). -- To create a backward compatible **Fabric Native Component**, follow [this guide](backward-compatibility-fabric-components). +- To create a backward compatible **TurboModule**, follow [this guide](backward-compatibility-turbomodules). +- To create a backward compatible **Fabric Component**, follow [this guide](backward-compatibility-fabric-components). diff --git a/docs/the-new-architecture/landing-page.md b/docs/the-new-architecture/landing-page.md index e3531bc09c8..fd8abf53fcf 100644 --- a/docs/the-new-architecture/landing-page.md +++ b/docs/the-new-architecture/landing-page.md @@ -11,9 +11,9 @@ Starting from version 0.68, React Native provides the New Architecture, which of To achieve these benefits, we had to rethink how Native Modules and Native Components work. This led us to develop the [Pillars of the New Architecture](pillars): -- [The New Native Module System - Turbo Modules](pillars-turbomodules), a framework to support efficient and flexible integration with native code -- [The New Native Renderer - Fabric](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering -- [The Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture via static typing in JavaScript +- [TurboModules](pillars-turbomodules), a framework to support efficient and flexible integration with native code +- [Fabric renderer and components](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering +- [Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture via static typing in JavaScript ## Get Started with the New Architecture diff --git a/docs/the-new-architecture/pillars-codegen.md b/docs/the-new-architecture/pillars-codegen.md index e34013a7c1d..d736c340546 100644 --- a/docs/the-new-architecture/pillars-codegen.md +++ b/docs/the-new-architecture/pillars-codegen.md @@ -11,7 +11,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con The **Codegen** is not a proper pillar, but it is a tool that can be used to avoid writing a lot of repetitive code. Using **Codegen** is not mandatory: all the code that is generated by it can also be written manually. However, it generates scaffolding code that could save you a lot of time. -The **Codegen** is invoked automatically by React Native every time an iOS or Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**Turbo Native Modules**](./pillars-turbomodules) and [**Fabric Native Components**](./pillars-fabric-components), for example. +The **Codegen** is invoked automatically by React Native every time an iOS or Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**TurboModules**](./pillars-turbomodules) and [**Fabric Components**](./pillars-fabric-components), for example. This guide teaches how to configure the **Codegen**, and how to invoke it manually for each platform, and describes the generated code. @@ -35,12 +35,12 @@ Previous versions of React Native uses a version of **Codegen** that requires a Then, add the module that requires the **Codegen** as an NPM dependency of the app: ```sh -yarn add +yarn add ``` -See how to create a [Turbo Native Module](pillars-turbomodules) or a [Fabric Native Component](pillars-fabric-components) to get more information on how to configure them. +See how to create a [TurboModule](pillars-turbomodules) or a [Fabric Component](pillars-fabric-components) to get more information on how to configure them. -The rest of this guide assumes that you have a `Turbo Native Module` and/or a `Fabric Native Component` properly set up. +The rest of this guide assumes that you have a `TurboModule` and/or a `Fabric Component` properly set up. # iOS @@ -58,7 +58,7 @@ node node_modules/react_native/scripts/generate-artifacts.js \ --outputPath \ ``` -Given that the app has `Turbo Native Modules` and/or `Fabric Native Components` configured as a dependency, **Codegen** looks for all of them and generates the code in the path you provided. +Given that the app has `TurboModules` and/or `Fabric Components` configured as a dependency, **Codegen** looks for all of them and generates the code in the path you provided. ## The Generated Code @@ -106,50 +106,29 @@ Then, there is an `ios` folder that contains: - A custom folder for each TurboModule. - The header (`.h`) and implementation (`.mm`) files for the `RCTThirdPartyFabricComponentsProvider`. -- A base `react/renderer/components` folder which contains a custom folder for each `Fabric Native Component`. +- A base `react/renderer/components` folder which contains a custom folder for each `Fabric Component`. -In the example above, there are both a TurboModule and a set of Fabric Native Components. These are generated by React Native itself: `FBReactNativeSpec` and `rncore`. These modules will always appear even if you don't have any extra TurboModule or Fabric Native Component: React Native requires them in order to work properly. +In the example above, there are both a TurboModule and a set of Fabric Components. These are generated by React Native itself: `FBReactNativeSpec` and `rncore`. These modules will always appear even if you don't have any extra TurboModule or Fabric Component: React Native requires them in order to work properly. -### Turbo Native Modules +### TurboModules -Each folder contains two files: an interface file and an implementation file. +Each TurboModule's folder contains two files: an interface file and an implementation file. -<<<<<<< HEAD The interface files have the same name as that of the TurboModule and contain methods to initialize the JSI interface. -||||||| parent of 1f97265d (Clarify New Architecture Terminology) -The interface files have the same name of the TurboModule and they contain methods to initialize the JSI interface. -======= -The interface files have the same name of the Turbo Native Module and they contain methods to initialize the JSI interface. - -> > > > > > > 1f97265d (Clarify New Architecture Terminology) The implementation files, instead, have the `-generated` suffix and contain the logic to invoke the native methods from JS and vice-versa. -### Fabric Native Components +### Fabric Components -<<<<<<< HEAD The content of each Fabric Component folder contains several files. The basic element for a Fabric Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore, it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. -||||||| parent of 1f97265d (Clarify New Architecture Terminology) -The content of each Fabric Component folder contains several files. The basic element for a Fabric Componenent is the `ShadowNode`: it represents a node in the React absract tree. The `ShadowNode` represents a React entity, therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. -======= -The content of each Fabric Native Component folder contains several files. The basic element for a Fabric Componenent is the `ShadowNode`: it represents a node in the React absract tree. The `ShadowNode` represents a React entity, therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. - -> > > > > > > 1f97265d (Clarify New Architecture Terminology) -Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Native Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. +Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. For further details about how Fabric works, have a look at the [Renderer](/architecture/fabric-renderer) section. ### RCTThirdPartyFabricComponentsProvider -<<<<<<< HEAD These are interface and implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Component. Once React Native has a handle to that class, it can instantiate it. -||||||| parent of 1f97265d (Clarify New Architecture Terminology) -These are an interface and an implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Component. Once React Native has an handle to that class, it can instantiate it. -======= -These are an interface and an implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Native Component. Once React Native has an handle to that class, it can instantiate it. - -> > > > > > > 1f97265d (Clarify New Architecture Terminology) # Android @@ -166,18 +145,11 @@ After that, you can navigate into the `SampleApp/android` folder and run: ./gradlew generateCodegenArtifactsFromSchema ``` -<<<<<<< HEAD These tasks invoke the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. -||||||| parent of 1f97265d (Clarify New Architecture Terminology) -This tasks invokes the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. -======= -This tasks invokes the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Native Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. - -> > > > > > > 1f97265d (Clarify New Architecture Terminology) ## The Generated Code -Once the Gradle task completes, you can see different structures for a Turbo Native Module or for a Fabric Native Component. The following tab shows how they appear: +Once the Gradle task completes, you can see different structures for a TurboModule or for a Fabric Component. The following tab shows how they appear: @@ -243,32 +215,18 @@ codegen Java can't interoperate seamlessly with C++ as Objective-C++ does. To work properly, **Codegen** creates some bridging between the Java and the C++ world in the `jni` folder, where the Java Native Interfaces are defined. -<<<<<<< HEAD Notice that both TurboModules and Fabric Components come with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. -||||||| parent of 1f97265d (Clarify New Architecture Terminology) -Notice that both TurboModules and Fabric Components comes with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. -======= -Notice that both Turbo Native Modules and Fabric Native Components comes with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. - -> > > > > > > 1f97265d (Clarify New Architecture Terminology) -### Turbo Native Module +### TurboModule The **Codegen** generates a Java abstract class in the `java` package with the same name as that of the TurboModule. This abstract class has to be implemented by the JNI C++ implementation. Then, it generates the C++ files in the `jni` folder. They follow the same iOS convention: there is an interface called `MyTurbomodule.h` and an implementation file called `MyTurbomodule-generated.cpp`. The former is an interface that allows React Native to initialize the JSI interface for the TurboModule. The latter is the implementation file which contains the logic to invoke the native method from JS and vice-versa. -### Fabric Native Component +### Fabric Component -The **Codegen** for a Fabric Native Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Native Component](./pillars-fabric-components) for details). +The **Codegen** for a Fabric Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Component](./pillars-fabric-components) for details). Then, there is a layer of JNI C++ files that are used by Fabric to render the components. The basic element for a Fabric Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. -<<<<<<< HEAD The **Codegen** also creates a `ComponentDescriptor.h`, which is required to get a proper handle on the Fabric Component. -||||||| parent of 1f97265d (Clarify New Architecture Terminology) -The **Codegen** also creates a `ComponentDescriptor.h` which is required to get a proper handle to the Fabric Component. -======= -The **Codegen** also creates a `ComponentDescriptor.h` which is required to get a proper handle to the Fabric Native Component. - -> > > > > > > 1f97265d (Clarify New Architecture Terminology) diff --git a/docs/the-new-architecture/pillars-fabric-components.md b/docs/the-new-architecture/pillars-fabric-components.md index 8b4af25fad4..fa9fd98321c 100644 --- a/docs/the-new-architecture/pillars-fabric-components.md +++ b/docs/the-new-architecture/pillars-fabric-components.md @@ -1,6 +1,6 @@ --- id: pillars-fabric-components -title: Fabric Native Components +title: Fabric Components --- import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; @@ -9,24 +9,24 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; -A Fabric Native Component is a Native Component rendered on the screen using the [Fabric Renderer](https://reactnative.dev/architecture/fabric-renderer). Using Fabric Native Components instead of Legacy Native Components allows us to reap all the [benefits](./why) of the **New Architecture**: +A Fabric Component is a UI component rendered on the screen using the [Fabric Renderer](https://reactnative.dev/architecture/fabric-renderer). Using Fabric Components instead of Native Components allows us to reap all the [benefits](./why) of the **New Architecture**: - Strongly typed interfaces that are consistent across platforms. - The ability to write your code in C++, either exclusively or integrated with another native platform language, hence reducing the need to duplicate implementations across platforms. - The use of JSI, a JavaScript interface for native code, which allows for more efficient communication between native and JavaScript code than the bridge. -A Fabric Native Component is created starting from a **JavaScript specification**. Then [**Codegen**](./pillars-codegen) creates some C++ scaffolding code to connect the component-specific logic (for example, accessing some native platform capability) to the rest of the React Native infrastructure. The C++ code is the same for all the platforms. Once the component is properly connected with the scaffolding code, it is ready to be imported and used by an app. +A Fabric Component is created starting from a **JavaScript specification**. Then [**Codegen**](./pillars-codegen) creates some C++ scaffolding code to connect the component-specific logic (for example, accessing some native platform capability) to the rest of the React Native infrastructure. The C++ code is the same for all the platforms. Once the component is properly connected with the scaffolding code, it is ready to be imported and used by an app. -The following section guides you through the creation of a Fabric Native Component, step-by-step, targeting React Native 0.70.0. +The following section guides you through the creation of a Fabric Component, step-by-step, targeting React Native 0.70.0. :::caution -Fabric Native Components only works with the **New Architecture** enabled. +Fabric Components only works with the **New Architecture** enabled. To migrate to the **New Architecture**, follow the [Migration guide](../new-architecture-intro) ::: -## How to Create a Fabric Native Components +## How to Create a Fabric Components -To create a Fabric Native Component, you have to follow these steps: +To create a Fabric Component, you have to follow these steps: 1. Define a set of JavaScript specifications. 2. Configure the component so that **Codegen** can create the shared code and it can be added as a dependency for an app. @@ -36,9 +36,9 @@ Once these steps are done, the component is ready to be consumed by an app. The ## 1. Folder Setup -In order to keep the component decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Fabric Native Component that can be released as open-source libraries later. +In order to keep the component decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Fabric Component that can be released as open-source libraries later. -For this guide, you are going to create a Fabric Native Component that centers some text on the screen. +For this guide, you are going to create a Fabric Component that centers some text on the screen. Create a new folder at the same level of the app and call it `RTNCenteredText`. @@ -108,7 +108,7 @@ export default codegenNativeComponent( -At the beginning of the spec files, there are the imports. The most important imports, required by every Fabric Native Component are: +At the beginning of the spec files, there are the imports. The most important imports, required by every Fabric Component are: - The `HostComponent`: type the exported component needs to conform to. - The `codegenNativeComponent` function: responsible to actually register the component in the JavaScript runtime. @@ -119,7 +119,7 @@ Finally, the spec file exports the returned value of the `codegenNativeComponent :::caution The JavaScript files imports types from libraries, without setting up a proper node module and installing its dependencies. The outcome of this is that the IDE may have troubles resolving the import statements and it can output errors and warnings. -These will disappear as soon as the Fabric Native Component is added as a dependency of a React Native app. +These will disappear as soon as the Fabric Component is added as a dependency of a React Native app. ::: ## 3. Component Configuration @@ -136,7 +136,7 @@ The shared configuration is a `package.json` file that will be used by yarn when { "name": "rtn-centered-text", "version": "0.0.1", - "description": "Showcase a Fabric Native Component with a centered text", + "description": "Showcase a Fabric Component with a centered text", "react-native": "js/index", "source": "js/index", "files": [ @@ -178,7 +178,7 @@ Then there are the dependencies for this package. For this guide, you need `reac Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a Fabric Native Component, thus the value to use is `components`. +- `type`: The type of module contained by this package. In this case, it is a Fabric Component, thus the value to use is `components`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. ### iOS: Create the `.podspec` file @@ -350,7 +350,7 @@ The last step requires you to write some native code to connect the JavaScript s 1. Run **Codegen** to see what would be generated. 2. Write the native code that will make it work. -When developing a React Native app that uses a Fabric Native Component, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a Fabric Component as a library, it needs to reference the generated code, and it is useful to see what the app will generate. +When developing a React Native app that uses a Fabric Component, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a Fabric Component as a library, it needs to reference the generated code, and it is useful to see what the app will generate. As the first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](./pillars-codegen.md). @@ -456,11 +456,11 @@ RCT_EXPORT_VIEW_PROPERTY(text, NSString) @end ``` -This file is the manager for the Fabric Native Component. React Native runtime uses manager objects to register the modules, properties and methods to make them available to the JavaScript side. +This file is the manager for the Fabric Component. React Native runtime uses manager objects to register the modules, properties and methods to make them available to the JavaScript side. The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that Fabric can retrieve and instantiate it. -Then, you have to expose the `text` property for the Fabric Native Component. This is done with the `RCT_EXPORT_VIEW_PROPERTY` macro, specifying a name and a type. +Then, you have to expose the `text` property for the Fabric Component. This is done with the `RCT_EXPORT_VIEW_PROPERTY` macro, specifying a name and a type. :::info There are other macros that can be used to export custom properties, emitters, and other constructs. You can view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Views/RCTViewManager.h). @@ -567,7 +567,7 @@ The component has to conform to a specific protocol generated by **Codegen**, in Then, the file defines a static `(ComponentDescriptorProvider)componentDescriptorProvider` method which Fabric uses to retrieve the descriptor provider to instantiate the object. -Then, there is the constructor of the view: the `init` method. In this method, it is important to create a `defaultProps` struct using the `RTNCenteredTextProps` type from **Codegen**. You need to assign it to the private `_props` to initialize the Fabric Native Component correctly. The remaining part of the initializer is standard Objective-C code to create views and layout them with AutoLayout. +Then, there is the constructor of the view: the `init` method. In this method, it is important to create a `defaultProps` struct using the `RTNCenteredTextProps` type from **Codegen**. You need to assign it to the private `_props` to initialize the Fabric Component correctly. The remaining part of the initializer is standard Objective-C code to create views and layout them with AutoLayout. The last two pieces are the `updateProps` method and the `RTNCenteredTextCls` method. @@ -576,7 +576,7 @@ The `updateProps` method is invoked by Fabric every time a prop changes in JavaS Finally, the `RTNCenteredTextCls` is another static method used to retrieve the correct instance of the class at runtime. :::caution -Differently from Legacy Native Components, Fabric requires to manually implement the `updateProps` method. It's not enough to export properties with the `RCT_EXPORT_XXX` and `RCT_REMAP_XXX` macros. +Differently from Native Components, Fabric requires to manually implement the `updateProps` method. It's not enough to export properties with the `RCT_EXPORT_XXX` and `RCT_REMAP_XXX` macros. ::: ### Android @@ -630,13 +630,13 @@ codegen └── schema.json ``` -You can see that the content of the `codegen/jni/react/renderer/components/RTNCenteredTextSpecs` looks similar to the files created by the iOS counterpart. The `Android.mk` and `CMakeList.txt` files configure the Fabric Native Component in the app, while the `RTNCenteredTextManagerDelegate.java` and `RTNCenteredTextManagerInterface.java` files are meant use in your manager. +You can see that the content of the `codegen/jni/react/renderer/components/RTNCenteredTextSpecs` looks similar to the files created by the iOS counterpart. The `Android.mk` and `CMakeList.txt` files configure the Fabric Component in the app, while the `RTNCenteredTextManagerDelegate.java` and `RTNCenteredTextManagerInterface.java` files are meant use in your manager. See the [Codegen](./pillars-codegen) section for further details on the generated files. #### Write the Native Android Code -The native code for the Android side of a Fabric Native Components requires three pieces: +The native code for the Android side of a Fabric Components requires three pieces: 1. A `RTNCenteredText.java` that represents the actual view. 2. A `RTNCenteredTextManager.java` to instantiate the view. @@ -788,11 +788,11 @@ public class RTNCenteredTextPackage implements ReactPackage { } ``` -The added lines instantiate a new `RTNCenteredTextManager` object so that the React Native runtime can use it to render our Fabric Native Component. +The added lines instantiate a new `RTNCenteredTextManager` object so that the React Native runtime can use it to render our Fabric Component. -## 5. Adding the Fabric Native Component To Your App +## 5. Adding the Fabric Component To Your App -This is the last step to finally see your Fabric Native Component running on your app. +This is the last step to finally see your Fabric Component running on your app. ### Shared diff --git a/docs/the-new-architecture/pillars-turbomodule.md b/docs/the-new-architecture/pillars-turbomodule.md index 29f8c2a775a..9452acaf086 100644 --- a/docs/the-new-architecture/pillars-turbomodule.md +++ b/docs/the-new-architecture/pillars-turbomodule.md @@ -1,6 +1,6 @@ --- id: pillars-turbomodules -title: Turbo Native Modules +title: TurboModules --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; @@ -10,23 +10,23 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; If you've worked with React Native, you may be familiar with the concept of [Native Modules](../native-modules-intro.md), which allow JavaScript and platform-native code to communicate over the React Native "bridge", which handles cross-platform serialization via JSON. -Turbo Native Modules are the next iteration on Native Modules that provide a few extra [benefits](./why): +TurboModules are the next iteration on Native Modules that provide a few extra [benefits](./why): - Strongly typed interfaces that are consistent across platforms - The ability to write your code in C++, either exclusively or integrated with another native platform language, reducing the need to duplicate implementations across platforms - Lazy loading of modules, allowing for faster app startup - The use of JSI, a JavaScript interface for native code, allows for more efficient communication between native and JavaScript code than the bridge -This guide will show you how to create a basic Turbo Native Module compatible with React Native 0.70.0. +This guide will show you how to create a basic TurboModule compatible with React Native 0.70.0. :::caution -Turbo Native Modules only work with the **New Architecture** enabled. +TurboModules only work with the **New Architecture** enabled. To migrate to the **New Architecture**, follow the [Migration guide](../new-architecture-intro) ::: -## How to Create a Turbo Native Module +## How to Create a TurboModule -To create a Turbo Native Module, we need to: +To create a TurboModule, we need to: 1. Define the JavaScript specification. 2. Configure the module so that Codegen can generate the scaffolding. @@ -34,7 +34,7 @@ To create a Turbo Native Module, we need to: ## 1. Folder Setup -In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Turbo Native Modules that can be released as open-source libraries later. +In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing TurboModules that can be released as open-source libraries later. Next to your application, create a folder called `RTNCalculator`. **RTN** stands for "**R**eac**t** **N**ative", and is a recommended prefix for React Native modules. @@ -97,12 +97,12 @@ export default TurboModuleRegistry.get( At the beginning of the spec files are the imports: -- The `TurboModule` type, which defines the base interface for all Turbo Native Modules -- The `TurboModuleRegistry` JavaScript module, which contains functions for loading Turbo Native Modules +- The `TurboModule` type, which defines the base interface for all TurboModules +- The `TurboModuleRegistry` JavaScript module, which contains functions for loading TurboModules -The second section of the file contains the interface specification for the Turbo Native Module. In this case, the interface defines the `add` function, which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a Turbo Native Module. +The second section of the file contains the interface specification for the TurboModule. In this case, the interface defines the `add` function, which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a TurboModule. -Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the Turbo Native Module if it's available. +Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the TurboModule if it's available. :::caution We are writing JavaScript files importing types from libraries, without setting up a proper node module and installing its dependencies. Your IDE will not be able to resolve the import statements and you may see errors and warnings. This is expected and will not cause problems when you add the module to your app. @@ -122,7 +122,7 @@ The shared configuration is a `package.json` file used by yarn when installing y { "name": "rtn-calculator", "version": "0.0.1", - "description": "Add numbers with Turbo Native Modules", + "description": "Add numbers with TurboModules", "react-native": "js/index", "source": "js/index", "files": [ @@ -167,7 +167,7 @@ Then there are the dependencies for this package. For this guide, you need `reac Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a Turbo Native Module; thus, the value to use is `modules`. +- `type`: The type of module contained by this package. In this case, it is a TurboModule; thus, the value to use is `modules`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. - `android.javaPackageName`: the package to use in the Java files generated by **Codegen**. @@ -329,12 +329,12 @@ React Native uses the `ReactPackage` interface to understand what native classes ## 4. Native Code -For the final step in getting your Turbo Native Module ready to go, you'll need to write some native code to connect the JavaScript side to the native platforms. This process requires two main steps: +For the final step in getting your TurboModule ready to go, you'll need to write some native code to connect the JavaScript side to the native platforms. This process requires two main steps: - Run **Codegen** to see what it generates. - Write your native code, implementing the generated interfaces. -When developing a React Native app that uses a Turbo Native Module, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore, useful to see what the app will generate. +When developing a React Native app that uses a TurboModule, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore, useful to see what the app will generate. As the first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](pillars-codegen.md). @@ -390,7 +390,7 @@ generated └── ShadowNodes.h ``` -The relevant path for the Turbo Native Module interface is `generated/build/generated/ios/RTNCalculatorSpec`. +The relevant path for the TurboModule interface is `generated/build/generated/ios/RTNCalculatorSpec`. See the [Codegen](./pillars-codegen) section for further details on the generated files. @@ -407,7 +407,7 @@ rm -rf build #### Write the Native iOS Code -Now add the Native code for your Turbo Native Module. Create two files in the `RTNCalculator/ios` folder: +Now add the Native code for your TurboModule. Create two files in the `RTNCalculator/ios` folder: 1. The `RTNCalculator.h`, a header file for the module. 2. The `RTNCalculator.mm`, the implementation of the module. @@ -456,11 +456,11 @@ RCT_REMAP_METHOD(add, addA:(NSInteger)a @end ``` -The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that React Native can load the Turbo Native Module. +The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that React Native can load the TurboModule. Then the `RCT_REMAP_METHOD` macro is used to expose the `add` method. -Finally, the `getTurboModule` method gets an instance of the Turbo Native Module so that the JavaScript side can invoke its methods. The function is defined in (and requested by) the `RTNCalculatorSpec.h` file that was generated earlier by Codegen. +Finally, the `getTurboModule` method gets an instance of the TurboModule so that the JavaScript side can invoke its methods. The function is defined in (and requested by) the `RTNCalculatorSpec.h` file that was generated earlier by Codegen. :::info There are other macros that can be used to export modules and methods. You view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Base/RCTBridgeModule.h). @@ -516,7 +516,7 @@ codegen #### Write the Native Android Code -The native code for the Android side of a Turbo Native Module requires: +The native code for the Android side of a TurboModule requires: 1. to create a `RTNCalculatorModule.java` that implements the module. 2. to update the `RTNCalculatorPackage.java` created in the previous step. @@ -628,9 +628,9 @@ public class CalculatorPackage extends TurboReactPackage { This is the last piece of Native Code for Android. It defines the `TurboReactPackage` object that will be used by the app to load the module. -## 5. Adding the Turbo Native Module to your App +## 5. Adding the TurboModule to your App -Now you can install and use the Turbo Native Module in your app. +Now you can install and use the TurboModule in your app. ### Shared @@ -667,7 +667,7 @@ Android configuration requires to enable the **New Architecture**: ### JavaScript -Now you can use your Turbo Native Module calculator in your app! +Now you can use your TurboModule calculator in your app! Here's an example App.js file using the `add` method: @@ -711,4 +711,4 @@ const App: () => Node = () => { export default App; ``` -Try this out to see your Turbo Native Module in action! +Try this out to see your TurboModule in action! diff --git a/docs/the-new-architecture/pillars.md b/docs/the-new-architecture/pillars.md index 14fd75eb8cf..05a828af51c 100644 --- a/docs/the-new-architecture/pillars.md +++ b/docs/the-new-architecture/pillars.md @@ -9,19 +9,12 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; The New Architecture is composed mainly of two pillars: -- [The New Native Module System - Turbo Modules](pillars-turbomodules) -- [The New Renderer - Fabric](pillars-fabric-components). +- [TurboModules](pillars-turbomodules) +- [Fabric Components](pillars-fabric-components). -The core concepts of React Native still holds true in the New Architecture: Native Modules are the preferred way to create libraries that leverage some platform-specific API. Native Components are the preferred way to create reusable UI components, providing a native experience to the users. +TurboModules are the preferred way to create libraries that leverage some platform-specific API. Fabric Components are the preferred way to create reusable UI components, providing a native experience to the users. -The main goal of this section is to drive the reader through a step-by-step guide to create their first Native Module or Component which is compatible with the New Architecture. - -:::info -For the sake of this guide we're going to use the following **terminology**: - -- **Legacy Native Components** & **Legacy Native Modules** - To refer to Modules and Components which are running on the old React Native architecture. -- **Fabric Native Components** & **Turbo Native Modules** - To refer to Modules and Components which have been adapted to work well with the New Architecture, namely the new renderer and the new Native Module System. For brevity you might find them referred as **Fabric Components** and **Turbo Modules** - ::: +The main goal of this section is to drive the reader through a step-by-step guide to create their first TurboModule or Fabric Component. The next sections contain a high-level overview of the pillars and the steps to create them. To create one of these pillars, the steps are: @@ -33,7 +26,7 @@ The next sections contain a high-level overview of the pillars and the steps to Finally, we dive a little deeper into the [Codegen](pillars-codegen) process that is required to create all the C++ types and files used by our components, including some useful steps to work comfortably while developing the component. :::caution -The app has to run with the **New Architecture enabled to integrate a Turbo Native Module or a Fabric Native Component** in an app. +The app has to run with the **New Architecture enabled to integrate a TurboModule or a Fabric Component** in an app. To create a new app adopting the New Architecture, refer to the [Using the App Template](use-app-template) section. To migrate an existing app to the New Architecture, refer to the [Migration](../new-architecture-intro) guide. diff --git a/docs/the-new-architecture/use-app-template.md b/docs/the-new-architecture/use-app-template.md index 53f96acc3f6..8abd06fb9a8 100644 --- a/docs/the-new-architecture/use-app-template.md +++ b/docs/the-new-architecture/use-app-template.md @@ -123,8 +123,8 @@ For further explanations of what each file is doing, check out these guides to w #### Android -- [Enabling the New Native Module System (Turbo Module) on Android](new-architecture-app-modules-android.md) -- [Enabling the New Renderer (Fabric) on Android](new-architecture-app-renderer-android.md) +- [Enabling TurboModules on Android](new-architecture-app-modules-android.md) +- [Enabling Fabric on Android](new-architecture-app-renderer-android.md) #### iOS diff --git a/docs/the-new-architecture/why.md b/docs/the-new-architecture/why.md index 964cfb0e9ef..84b8fe62e0e 100644 --- a/docs/the-new-architecture/why.md +++ b/docs/the-new-architecture/why.md @@ -35,7 +35,7 @@ This idea allowed the unlocking of several benefits: - **Code sharing:** by introducing C++, it is now possible to abstract all the platform agnostic code and to share it with ease between the platforms. - **Type safety:** to make sure that JS can properly invoke methods on C++ objects and vice-versa, a layer of code automatically generated has been added. The code is generated starting from some JS specification that must be typed through Flow or TypeScript. -These advantages are the foundations of the [New Native Module System](pillars-turbomodules) and a jumping stone to further enhancements. For example, it has been possible to develop a [new renderer](/architecture/fabric-renderer) which offers faster and more performant [Native Components](pillars-fabric-components). +These advantages are the foundations of the [TurboModule](pillars-turbomodules) system and a jumping stone to further enhancements. For example, it has been possible to develop a new renderer that is faster and more performant: [Fabric](/architecture/fabric-renderer) and its [Fabric Components](pillars-fabric-components). ## Further Reading From c084b5a413a1f2345ae5289b7901eb91773b0279 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 9 Sep 2022 21:18:04 +0100 Subject: [PATCH 19/88] Clarify New Architecture Terminology - Take 2 (#3316) --- docs/new-architecture-app-intro.md | 2 +- docs/new-architecture-app-modules-android.md | 10 ++-- docs/new-architecture-app-renderer-android.md | 2 +- docs/new-architecture-appendix.md | 17 +++++-- docs/new-architecture-intro.md | 4 +- docs/new-architecture-library-intro.md | 6 +-- docs/new-architecture-library-ios.md | 2 +- docs/react-18-and-react-native.md | 2 +- .../_markdown_native_deprecation.mdx | 2 +- ...ackward-compatibility-fabric-components.md | 47 ++++++++++-------- .../backward-compatibility-turbomodules.md | 45 +++++++++-------- .../backward-compatibility.md | 6 +-- docs/the-new-architecture/landing-page.md | 6 +-- docs/the-new-architecture/pillars-codegen.md | 42 ++++++++-------- .../pillars-fabric-components.md | 46 +++++++++--------- .../pillars-turbomodule.md | 48 +++++++++---------- docs/the-new-architecture/pillars.md | 17 +++++-- docs/the-new-architecture/use-app-template.md | 4 +- docs/the-new-architecture/why.md | 2 +- 19 files changed, 170 insertions(+), 140 deletions(-) diff --git a/docs/new-architecture-app-intro.md b/docs/new-architecture-app-intro.md index 2b1de555728..c0d56f91a71 100644 --- a/docs/new-architecture-app-intro.md +++ b/docs/new-architecture-app-intro.md @@ -188,7 +188,7 @@ React Native also supports a local version of this file `.xcode.env.local`. This ## iOS - Use Objective-C++ (`.mm` extension) -TurboModules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. +Turbo Native Modules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. :::important diff --git a/docs/new-architecture-app-modules-android.md b/docs/new-architecture-app-modules-android.md index b3e8fddfb7c..02069ffac51 100644 --- a/docs/new-architecture-app-modules-android.md +++ b/docs/new-architecture-app-modules-android.md @@ -100,7 +100,7 @@ yarn react-native run-android ## 2. Java/Kotlin - Provide a `ReactPackageTurboModuleManagerDelegate` -Now is time to actually use the TurboModule. +Now is time to actually use the Turbo Native Module. First, we will need to create a `ReactPackageTurboModuleManagerDelegate` subclass, like the following: @@ -193,7 +193,7 @@ protected constructor( Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `project()` inside the `CMakeLists.txt` file you created before. -This class will then be responsible of loading the TurboModules and will take care of loading the native library build with the NDK at runtime. +This class will then be responsible of loading the Turbo Native Modules and will take care of loading the native library build with the NDK at runtime. ## 3. Adapt your `ReactNativeHost` to use the `ReactPackageTurboModuleManagerDelegate` @@ -259,7 +259,7 @@ class MyApplication : Application(), ReactApplication { ## 4. Extend the `getPackages()` from your `ReactNativeHost` to use the TurboModule -Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created TurboModule. Update the method to include the following: +Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created Turbo Native Module. Update the method to include the following: @@ -493,7 +493,7 @@ std::shared_ptr MyApplicationModuleProvider(const std::string modul Please adapt the `samplelibrary.h` import to match the same library name you provided when building the apps. This is the C++ generated file that is created by the codegen. -Here you can also specify more than one provider, should you have more than one TurboModule. Specifically in this example we look for a TurboModule from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). +Here you can also specify more than one provider, should you have more than one Turbo Native Module. Specifically in this example we look for a Turbo Native Module from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). ```cpp #include "MyApplicationModuleProvider.h" @@ -532,7 +532,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { ## 6. Enable the `useTurboModules` flag in your Application `onCreate` -Now you can finally enable the `TurboModule `support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. +Now you can finally enable the `Turbo Native Module` support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. diff --git a/docs/new-architecture-app-renderer-android.md b/docs/new-architecture-app-renderer-android.md index 736abcb8f56..39bb732efbf 100644 --- a/docs/new-architecture-app-renderer-android.md +++ b/docs/new-architecture-app-renderer-android.md @@ -113,7 +113,7 @@ LOG Running "App" with {"fabric":true,"initialProps":{},"rootTag":1} ## Migrating Android ViewManagers -First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. +First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (Turbo Module) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. ### JavaScript changes diff --git a/docs/new-architecture-appendix.md b/docs/new-architecture-appendix.md index 56b3301423b..61bbc1377e3 100644 --- a/docs/new-architecture-appendix.md +++ b/docs/new-architecture-appendix.md @@ -7,7 +7,16 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; -## I. Flow Type to Native Type Mapping +## I. Terminology + +The whole New Architecture related guides will stick to the following **terminology**: + +- **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. +- **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. +- **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Architecture, namely the new renderer. For brevity you might find them referred as **Fabric Components**. +- **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Architecture, namely the new Native Module System. For brevity you might find them referred as **Turbo Modules** + +## II. Flow Type to Native Type Mapping You may use the following table as a reference for which types are supported and what they map to in each platform: @@ -85,7 +94,7 @@ Callback functions are not type checked, and are generalized as `Object`s. You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository. ::: -## II. TypeScript to Native Type Mapping +## III. TypeScript to Native Type Mapping You may use the following table as a reference for which types are supported and what they map to in each platform: @@ -105,7 +114,7 @@ You may use the following table as a reference for which types are supported and You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository. -## III. Invoking the code-gen during development +## IV. Invoking the code-gen during development > This section contains information specific to v0.66 of React Native. @@ -182,7 +191,7 @@ node node_modules/react-native/scripts/generate-specs-cli.js \ In the above example, the code-gen script will generate several files: `MyLibSpecs.h` and `MyLibSpecs-generated.mm`, as well as a handful of `.h` and `.cpp` files, all located in the `ios` directory. -## IV. Note on Existing Apps +## V. Note on Existing Apps This guide provides instructions for migrating an application that is based on the default app template that is provided by React Native. If your app has deviated from the template, or you are working with an application that was never based off the template, then the following sections might help. diff --git a/docs/new-architecture-intro.md b/docs/new-architecture-intro.md index fce2e38630b..e5b224a1649 100644 --- a/docs/new-architecture-intro.md +++ b/docs/new-architecture-intro.md @@ -9,7 +9,7 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; # Getting Started with the New Architecture -This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **new NativeModule system (TurboModule) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps. +This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **New Native Module system (Turbo Module) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps. ## Table of Contents @@ -23,7 +23,7 @@ The guide is divided into five sections: - **Supporting the New Architecture in your App** - [Prerequisites for Supporting the New Architecture in your App](new-architecture-app-intro) - Android - - [Enabling the New NativeModule System (TurboModule) in your App](new-architecture-app-modules-android) + - [Enabling the New Native Module System (Turbo Module) in your App](new-architecture-app-modules-android) - [Enabling the New Renderer (Fabric) in your App](new-architecture-app-renderer-android) - [**React 18 & React Native**](react-18-and-react-native) - [**Troubleshooting**](new-architecture-troubleshooting) diff --git a/docs/new-architecture-library-intro.md b/docs/new-architecture-library-intro.md index 9d688a8151e..0d905261fb7 100644 --- a/docs/new-architecture-library-intro.md +++ b/docs/new-architecture-library-intro.md @@ -23,7 +23,7 @@ Currently, this guide is written under the assumption that you will be using [Fl To adopt the New Architecture, you start by creating these specs for your native modules and native components. You can do this prior to actually migrating to the New Architecture: the specs will be used later on to generate native interface code for all the supported platforms as a way to enforce uniform APIs across platforms. -#### Turbomodules +#### Turbo Native Modules JavaScript spec files **must** be named `Native.js` and they export a `TurboModuleRegistry` `Spec` object. The name convention is important because the Codegen process looks for modules whose `js` (`jsx`, `ts`, or `tsx`) spec file starts with the keyword `Native`. @@ -70,7 +70,7 @@ export default TurboModuleRegistry.get(''); -#### Fabric Components +#### Fabric Native Components JavaScript spec files **must** be named `NativeComponent.js` (for TypeScript use extension `.ts` or `.tsx`) and they export a `HostComponent` object. The name convention is important: the Codegen process looks for components whose spec file (either JavaScript or TypeScript) ends with the suffix `NativeComponent`. @@ -214,7 +214,7 @@ Codegen can be configured in the `package.json` file of your Library. Add the fo - The `codegenConfig` is the key used by the Codegen to verify that there is some code to generate. - The `name` field is the name of the library. -- The `type` field is used to identify the type of module we want to create. Our suggestion is to keep `all` to support libraries that contain both TurboModule and Fabric Components. +- The `type` field is used to identify the type of module we want to create. Our suggestion is to keep `all` to support libraries that contain both Turbo Native Module and Fabric Native Components. - The `jsSrcsDir` is the directory where the codegen will start looking for JavaScript specs. - The `android.javaPackageName` is the name of the package where the generated code wil end up. diff --git a/docs/new-architecture-library-ios.md b/docs/new-architecture-library-ios.md index 8eca9aa3184..1fb8eee0851 100644 --- a/docs/new-architecture-library-ios.md +++ b/docs/new-architecture-library-ios.md @@ -32,7 +32,7 @@ Pod::Spec.new do |s| } s.dependency "React-Core" - s.dependency "React-RCTFabric" # This is for Fabric Component + s.dependency "React-RCTFabric" # This is for Fabric Native Component s.dependency "React-Codegen" s.dependency "RCT-Folly" s.dependency "RCTRequired" diff --git a/docs/react-18-and-react-native.md b/docs/react-18-and-react-native.md index ed4a5d09eb6..33892b9e1d6 100644 --- a/docs/react-18-and-react-native.md +++ b/docs/react-18-and-react-native.md @@ -31,7 +31,7 @@ The concurrent features in React 18 are built on top of the new concurrent rende Previous versions of React Native built on the old architecture **cannot** support concurrent rendering or concurrent features. This is because the old architecture relied on mutating the native trees, which doesn’t allow for React to prepare multiple versions of the tree at the same time. -Fortunately, the New Architecture was written bottom-up with concurrent rendering in mind, and is fully compatible with React 18. This means, in order to upgrade to React 18 in your React Native app, your application needs to be migrated to the React Native's New Architecture including Fabric and TurboModules. +Fortunately, the New Architecture was written bottom-up with concurrent rendering in mind, and is fully compatible with React 18. This means, in order to upgrade to React 18 in your React Native app, your application needs to be migrated to the React Native's New Architecture including Fabric Native Components and Turbo Native Modules. ## React 18 enabled by default diff --git a/docs/the-new-architecture/_markdown_native_deprecation.mdx b/docs/the-new-architecture/_markdown_native_deprecation.mdx index 569a078d147..390bfcdc3de 100644 --- a/docs/the-new-architecture/_markdown_native_deprecation.mdx +++ b/docs/the-new-architecture/_markdown_native_deprecation.mdx @@ -1,4 +1,4 @@ :::info Native Module and Native Components are our stable technologies used by the legacy architecture. -They will be deprecated in the future when the New Architecture will be stable. The New Architecture uses [TurboModule](./the-new-architecture/pillars-turbomodules) and [Fabric Components](./the-new-architecture/pillars-fabric-components) to achieve similar results. +They will be deprecated in the future when the New Architecture will be stable. The New Architecture uses [Turbo Native Module](./the-new-architecture/pillars-turbomodules) and [Fabric Native Components](./the-new-architecture/pillars-fabric-components) to achieve similar results. ::: diff --git a/docs/the-new-architecture/backward-compatibility-fabric-components.md b/docs/the-new-architecture/backward-compatibility-fabric-components.md index 64f93c1834f..8f67e7dcc1d 100644 --- a/docs/the-new-architecture/backward-compatibility-fabric-components.md +++ b/docs/the-new-architecture/backward-compatibility-fabric-components.md @@ -1,6 +1,6 @@ --- id: backward-compatibility-fabric-components -title: Fabric Components as Native Components +title: Fabric Components as Legacy Native Components --- import Tabs from '@theme/Tabs'; @@ -12,28 +12,35 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -Creating a backward compatible Fabric Component requires the knowledge of how to create a Fabric Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). +Creating a backward compatible Fabric Native Component requires the knowledge of how to create a Legacy Native Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). -Fabric Components only work when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. +Fabric Native Components only work when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: -Creating a backward compatible Fabric Component lets your users continue to leverage your library independently from the architecture they use. The creation of such a component requires a few steps: +Creating a backward compatible Fabric Native Component lets your users continue to leverage your library independently from the architecture they use. The creation of such a component requires a few steps: 1. Configure the library so that dependencies are prepared to set up properly for both the Old and the New Architecture. 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. +- **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Native Renderer, Fabric. For brevity you might find them referred as **Fabric Components**. + ::: + While the last step is the same for all the platforms, the first two steps are different for iOS and Android. -## Configure the Fabric Component Dependencies +## Configure the Fabric Native Component Dependencies ### iOS -The Apple platform installs Fabric Components using [Cocoapods](https://cocoapods.org) as a dependency manager. +The Apple platform installs Fabric Native Components using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every Fabric Component defines a `podspec` that looks like this: +Every Fabric Native Component defines a `podspec` that looks like this: ```ruby require "json" @@ -104,13 +111,13 @@ This `if` guard prevents the dependencies from being installed when the environm ### Android -To create a module that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. +To create a Native Component that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. :::note Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: -To configure the Fabric Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: +To configure the Fabric Native Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: ```diff title="build.gradle" +// Add this function in case you don't have it already @@ -148,7 +155,7 @@ These changes do three main things: The second step is to instruct Xcode to avoid compiling all the lines using the New Architecture types and files when we are building an app with the Old Architecture. -A Fabric Component requires an header file and an implementation file to add the actual `View` to the module. +A Fabric Native Component requires an header file and an implementation file to add the actual `View` to the module. For example, the `RNMyComponentView.h` header file could look like this: @@ -236,15 +243,15 @@ As we can't use conditional compilation blocks on Android, we will define two di Therefore, you have to: -1. Create a Native Component in the `src/oldarch` path. See [this guide](../native-components-android) to learn how to create a Native Component. -2. Create a Fabric Component in the `src/newarch` path. See [this guide](pillars-fabric-components) to learn how to create a Fabric Component. +1. Create a Legacy Native Component in the `src/oldarch` path. See [this guide](../native-components-android) to learn how to create a Legacy Native Component. +2. Create a Fabric Native Component in the `src/newarch` path. See [this guide](pillars-fabric-components) to learn how to create a Fabric Native Component. and then instruct Gradle to decide which implementation to pick. -Some files can be shared between a Native and a Fabric Component: these should be created or moved into a folder that is loaded by both the architectures. These files are: +Some files can be shared between a Legacy and a Fabric Component: these should be created or moved into a folder that is loaded by both the architectures. These files are: - the `.java` that instantiate and configure the Android View for both the components. -- the `ManagerImpl.java` file where which contains the logic of the ViewManager that can be shared between the Native and the Fabric Component. +- the `ManagerImpl.java` file where which contains the logic of the ViewManager that can be shared between the Legacy and the Fabric Component. - the `Package.java` file used to load the component. The final folder structure looks like this: @@ -275,7 +282,7 @@ my-component └── package.json ``` -The code that should go in the `MyComponentViewManagerImpl.java` and that can be shared between the Native Component and the Fabric Component is, for example: +The code that should go in the `MyComponentViewManagerImpl.java` and that can be shared between the Native Component and the Fabric Native Component is, for example: ```java title="example of MyComponentViewManager.java" package com.MyComponent; @@ -296,7 +303,7 @@ public class MyComponentViewManagerImpl { } ``` -Then, the Native Component and the Fabric Component can be updated using the function declared in the shared manager. +Then, the Native Component and the Fabric Native Component can be updated using the function declared in the shared manager. For example, for a Native Component: @@ -330,7 +337,7 @@ public class MyComponentViewManager extends SimpleViewManager { } ``` -And, for a Fabric Component: +And, for a Fabric Native Component: ```java title="Fabric Component using the ViewManagerImpl" // Use the static NAME property from the shared implementation @@ -381,7 +388,7 @@ For a step-by-step example on how to achieve this, have a look at [this repo](ht The last step makes sure that the JavaScript behaves transparently to chosen architecture. -For a Fabric Component, the source of truth is the `NativeComponent.js` (or `.ts`) spec file. The app accesses the spec file like this: +For a Fabric Native Component, the source of truth is the `NativeComponent.js` (or `.ts`) spec file. The app accesses the spec file like this: ```ts import MyComponent from 'your-component/src/index'; @@ -431,5 +438,5 @@ Whether you are using Flow or TypeScript for your specs, we understand which arc Please note that the New Architecture is still experimental. The `global.nativeFabricUIManager` API might change in the future for a function that encapsulate this check. ::: -- If that object is `null`, then the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). -- If that object is set, the app is running with Fabric enabled, and it should use the `NativeComponent` spec to access the Fabric Component. +- If that object is `null`, then the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Legacy Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). +- If that object is set, the app is running with Fabric enabled, and it should use the `NativeComponent` spec to access the Fabric Native Component. diff --git a/docs/the-new-architecture/backward-compatibility-turbomodules.md b/docs/the-new-architecture/backward-compatibility-turbomodules.md index 9b636d4fb79..590220e6453 100644 --- a/docs/the-new-architecture/backward-compatibility-turbomodules.md +++ b/docs/the-new-architecture/backward-compatibility-turbomodules.md @@ -1,6 +1,6 @@ --- id: backward-compatibility-turbomodules -title: TurboModules as Native Modules +title: Turbo Modules as Legacy Native Modules --- import Tabs from '@theme/Tabs'; @@ -12,7 +12,7 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -Creating a backward compatible TurboModule requires the knowledge of how to create a TurboModule. To recall these concepts, have a look at this [guide](pillars-turbomodules). +Creating a backward compatible Turbo Native Module requires the knowledge of how to create a Legacy Native Module. To recall these concepts, have a look at this [guide](pillars-turbomodules). TurboModules only works when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: @@ -23,17 +23,24 @@ Creating a backward compatible TurboModule lets your users continue to leverage 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. +- **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Native Module System. For brevity you might find them referred as **Turbo Modules**. + ::: + While the last step is the same for all the platforms, the first two steps are different for iOS and Android. -## Configure the TurboModule Dependencies +## Configure the Turbo Native Module Dependencies ### iOS -The Apple platform installs TurboModules using [Cocoapods](https://cocoapods.org) as a dependency manager. +The Apple platform installs Turbo Native Modules using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every TurboModule defines a `podspec` that looks like this: +Every Turbo Native Module defines a `podspec` that looks like this: ```ruby require "json" @@ -109,7 +116,7 @@ To create a module that can work with both architectures, you need to configure Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure the maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: -To configure the TurboModule so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: +To configure the Turbo Native Module so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: ```diff title="build.gradle" +// Add this function in case you don't have it already @@ -156,7 +163,7 @@ The file to change is the module implementation file, which is usually a `` type, generated by The New Architecture. -The **goal** is to make sure that the `TurboModule` still builds with the Old Architecture. To achieve that, we can wrap the `#import ".h"` and the `getTurboModule:` function into an `#ifdef RCT_NEW_ARCH_ENABLED` compilation directive, as shown in the following example: +The **goal** is to make sure that the `Turbo Native Module` still builds with the Old Architecture. To achieve that, we can wrap the `#import ".h"` and the `getTurboModule:` function into an `#ifdef RCT_NEW_ARCH_ENABLED` compilation directive, as shown in the following example: ```diff #import ".h" @@ -181,19 +188,19 @@ This snippet uses the same `RCT_NEW_ARCH_ENABLED` flag used in the previous [sec ### Android -As we can't use conditional compilation blocks on Android, we will define two different source sets. This will allow to create a backward compatible TurboModule with the proper source that is loaded and compiled depending on the used architecture. +As we can't use conditional compilation blocks on Android, we will define two different source sets. This will allow to create a backward compatible Turbo Native Module with the proper source that is loaded and compiled depending on the used architecture. Therefore, you have to: -1. Create a Native Module in the `src/oldarch` path. See [this guide](../native-modules-intro) to learn how to create a Native Module. -2. Create a TurboModule in the `src/newarch` path. See [this guide](./pillars-turbomodules) to learn how to create a TurboModule +1. Create a Legacy Native Module in the `src/oldarch` path. See [this guide](../native-modules-intro) to learn how to create a Legacy Native Module. +2. Create a Turbo Native Module in the `src/newarch` path. See [this guide](./pillars-turbomodules) to learn how to create a Turbo Native Module and then instruct Gradle to decide which implementation to pick. -Some files can be shared between a Native Module and a TurboModule: these should be created or moved into a folder that is loaded by both the architectures. These files are: +Some files can be shared between a Legacy Native Module and a Turbo Native Module: these should be created or moved into a folder that is loaded by both the architectures. These files are: - the `Package.java` file used to load the module. -- a `Impl.java` file where we can put the code that both the Native Module and the TurboModule has to execute. +- a `Impl.java` file where we can put the code that both the Legacy Native Module and the Turbo Native Module has to execute. The final folder structure looks like this: @@ -222,7 +229,7 @@ my-module └── package.json ``` -The code that should go in the `MyModuleImpl.java`, and that can be shared by the Native Module and the TurboModule is, for example: +The code that should go in the `MyModuleImpl.java`, and that can be shared by the Legacy Native Module and the Turbo Native Module is, for example: ```java title="example of MyModuleImple.java" package com.MyModule; @@ -243,13 +250,13 @@ public class MyModuleImpl { } ``` -Then, the Native Module and the TurboModule can be updated with the following steps: +Then, the Legacy Native Module and the Turbo Native Module can be updated with the following steps: 1. Create a private instance of the `MyModuleImpl` class. 2. Initialize the instance in the module constructor. 3. Use the private instance in the modules methods. -For example, for a Native Module: +For example, for a Legacy Native Module: ```java title="Native Module using the Impl module" public class MyModule extends ReactContextBaseJavaModule { @@ -277,7 +284,7 @@ public class MyModule extends ReactContextBaseJavaModule { } ``` -And, for a TurboModule: +And, for a Turbo Native Module: ```java title="TurboModule using the Impl module" public class MyModule extends MyModuleSpec { @@ -313,7 +320,7 @@ For a step-by-step example on how to achieve this, have a look at [this repo](ht The last step makes sure that the JavaScript behaves transparently to chosen architecture. -For a TurboModule, the source of truth is the `Native.js` (or `.ts`) spec file. The app accesses the spec file like this: +For a Turbo Native Module, the source of truth is the `Native.js` (or `.ts`) spec file. The app accesses the spec file like this: ```ts import MyModule from 'your-module/src/index'; @@ -366,5 +373,5 @@ Whether you are using Flow or TypeScript for your specs, we understand which arc The `global.__turboModuleProxy` API may change in the future for a function that encapsulates this check. ::: -- If that object is `null`, the app has not enabled the TurboModule feature. It's running on the Old Architecture, and the fallback is to use the default [`NativeModule` implementation](../native-modules-intro). -- If that object is set, the app is running with the TurboModules enabled, and it should use the `Native` spec to access the TurboModule. +- If that object is `null`, the app has not enabled the Turbo Native Module feature. It's running on the Old Architecture, and the fallback is to use the default [`Legacy Native Module` implementation](../native-modules-intro). +- If that object is set, the app is running with the Turbo Native Modules enabled, and it should use the `Native` spec to access the Turbo Native Module. diff --git a/docs/the-new-architecture/backward-compatibility.md b/docs/the-new-architecture/backward-compatibility.md index 89c1f3ac73f..babe5507485 100644 --- a/docs/the-new-architecture/backward-compatibility.md +++ b/docs/the-new-architecture/backward-compatibility.md @@ -11,7 +11,7 @@ Creating a backward compatible module is important to provide a library that wor The trick to create a good backward compatible module is to minimize the changes required to adopt the new version. In that way, users of the module can smoothly move to the new version and migrate to the New Architecture when they are ready, ideally by issueing one different command. -To achieve this result, we have to perform few changes in our **TurboModule** and **Fabric Component** configurations. The steps we have to follow are: +To achieve this result, we have to perform few changes in our **Turbo Native Module** and **Fabric Native Component** configurations. The steps we have to follow are: 1. **Update the installation configuration** to avoid using code that is not needed by the Old Architecture. 1. **Update the code** to support both architectures. Both Android and iOS build pipelines gives you mechanism to provide a library that will compile with the correct React Native Architecture. @@ -21,5 +21,5 @@ To achieve this result, we have to perform few changes in our **TurboModule** an The next sections requires that you are familiar with the [Pillars](pillars) of the **New Architecture**. ::: -- To create a backward compatible **TurboModule**, follow [this guide](backward-compatibility-turbomodules). -- To create a backward compatible **Fabric Component**, follow [this guide](backward-compatibility-fabric-components). +- To create a backward compatible **Turbo Native Module**, follow [this guide](backward-compatibility-turbomodules). +- To create a backward compatible **Fabric Native Component**, follow [this guide](backward-compatibility-fabric-components). diff --git a/docs/the-new-architecture/landing-page.md b/docs/the-new-architecture/landing-page.md index fd8abf53fcf..e3531bc09c8 100644 --- a/docs/the-new-architecture/landing-page.md +++ b/docs/the-new-architecture/landing-page.md @@ -11,9 +11,9 @@ Starting from version 0.68, React Native provides the New Architecture, which of To achieve these benefits, we had to rethink how Native Modules and Native Components work. This led us to develop the [Pillars of the New Architecture](pillars): -- [TurboModules](pillars-turbomodules), a framework to support efficient and flexible integration with native code -- [Fabric renderer and components](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering -- [Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture via static typing in JavaScript +- [The New Native Module System - Turbo Modules](pillars-turbomodules), a framework to support efficient and flexible integration with native code +- [The New Native Renderer - Fabric](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering +- [The Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture via static typing in JavaScript ## Get Started with the New Architecture diff --git a/docs/the-new-architecture/pillars-codegen.md b/docs/the-new-architecture/pillars-codegen.md index d736c340546..0650926f789 100644 --- a/docs/the-new-architecture/pillars-codegen.md +++ b/docs/the-new-architecture/pillars-codegen.md @@ -11,7 +11,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con The **Codegen** is not a proper pillar, but it is a tool that can be used to avoid writing a lot of repetitive code. Using **Codegen** is not mandatory: all the code that is generated by it can also be written manually. However, it generates scaffolding code that could save you a lot of time. -The **Codegen** is invoked automatically by React Native every time an iOS or Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**TurboModules**](./pillars-turbomodules) and [**Fabric Components**](./pillars-fabric-components), for example. +The **Codegen** is invoked automatically by React Native every time an iOS or Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**Turbo Native Modules**](./pillars-turbomodules) and [**Fabric Native Components**](./pillars-fabric-components), for example. This guide teaches how to configure the **Codegen**, and how to invoke it manually for each platform, and describes the generated code. @@ -35,12 +35,12 @@ Previous versions of React Native uses a version of **Codegen** that requires a Then, add the module that requires the **Codegen** as an NPM dependency of the app: ```sh -yarn add +yarn add ``` -See how to create a [TurboModule](pillars-turbomodules) or a [Fabric Component](pillars-fabric-components) to get more information on how to configure them. +See how to create a [Turbo Native Module](pillars-turbomodules) or a [Fabric Native Component](pillars-fabric-components) to get more information on how to configure them. -The rest of this guide assumes that you have a `TurboModule` and/or a `Fabric Component` properly set up. +The rest of this guide assumes that you have a `Turbo Native Module` and/or a `Fabric Native Component` properly set up. # iOS @@ -58,7 +58,7 @@ node node_modules/react_native/scripts/generate-artifacts.js \ --outputPath \ ``` -Given that the app has `TurboModules` and/or `Fabric Components` configured as a dependency, **Codegen** looks for all of them and generates the code in the path you provided. +Given that the app has `Turbo Native Modules` and/or `Fabric Native Components` configured as a dependency, **Codegen** looks for all of them and generates the code in the path you provided. ## The Generated Code @@ -106,29 +106,29 @@ Then, there is an `ios` folder that contains: - A custom folder for each TurboModule. - The header (`.h`) and implementation (`.mm`) files for the `RCTThirdPartyFabricComponentsProvider`. -- A base `react/renderer/components` folder which contains a custom folder for each `Fabric Component`. +- A base `react/renderer/components` folder which contains a custom folder for each `Fabric Native Component`. -In the example above, there are both a TurboModule and a set of Fabric Components. These are generated by React Native itself: `FBReactNativeSpec` and `rncore`. These modules will always appear even if you don't have any extra TurboModule or Fabric Component: React Native requires them in order to work properly. +In the example above, there are both a TurboModule and a set of Fabric Native Components. These are generated by React Native itself: `FBReactNativeSpec` and `rncore`. These modules will always appear even if you don't have any extra TurboModule or Fabric Native Component: React Native requires them in order to work properly. -### TurboModules +### Turbo Native Modules -Each TurboModule's folder contains two files: an interface file and an implementation file. +Each folder contains two files: an interface file and an implementation file. -The interface files have the same name as that of the TurboModule and contain methods to initialize the JSI interface. +The interface files have the same name as that of the Turbo Native Module and contain methods to initialize the JSI interface. The implementation files, instead, have the `-generated` suffix and contain the logic to invoke the native methods from JS and vice-versa. -### Fabric Components +### Fabric Native Components -The content of each Fabric Component folder contains several files. The basic element for a Fabric Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore, it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. +The content of each Fabric Native Component folder contains several files. The basic element for a Fabric Native Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore, it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. -Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. +Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Fabric Native Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. For further details about how Fabric works, have a look at the [Renderer](/architecture/fabric-renderer) section. ### RCTThirdPartyFabricComponentsProvider -These are interface and implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Component. Once React Native has a handle to that class, it can instantiate it. +These are interface and implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Native Component. Once React Native has a handle to that class, it can instantiate it. # Android @@ -145,11 +145,11 @@ After that, you can navigate into the `SampleApp/android` folder and run: ./gradlew generateCodegenArtifactsFromSchema ``` -These tasks invoke the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. +These tasks invoke the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Native Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. ## The Generated Code -Once the Gradle task completes, you can see different structures for a TurboModule or for a Fabric Component. The following tab shows how they appear: +Once the Gradle task completes, you can see different structures for a Turbo Native Module or for a Fabric Native Component. The following tab shows how they appear: @@ -215,18 +215,18 @@ codegen Java can't interoperate seamlessly with C++ as Objective-C++ does. To work properly, **Codegen** creates some bridging between the Java and the C++ world in the `jni` folder, where the Java Native Interfaces are defined. -Notice that both TurboModules and Fabric Components come with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. +Notice that both Turbo Native Modules and Fabric Native Components come with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. -### TurboModule +### Turbo Native Module The **Codegen** generates a Java abstract class in the `java` package with the same name as that of the TurboModule. This abstract class has to be implemented by the JNI C++ implementation. Then, it generates the C++ files in the `jni` folder. They follow the same iOS convention: there is an interface called `MyTurbomodule.h` and an implementation file called `MyTurbomodule-generated.cpp`. The former is an interface that allows React Native to initialize the JSI interface for the TurboModule. The latter is the implementation file which contains the logic to invoke the native method from JS and vice-versa. -### Fabric Component +### Fabric Native Component -The **Codegen** for a Fabric Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Component](./pillars-fabric-components) for details). +The **Codegen** for a Fabric Native Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Native Component](./pillars-fabric-components) for details). Then, there is a layer of JNI C++ files that are used by Fabric to render the components. The basic element for a Fabric Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. -The **Codegen** also creates a `ComponentDescriptor.h`, which is required to get a proper handle on the Fabric Component. +The **Codegen** also creates a `ComponentDescriptor.h`, which is required to get a proper handle on the Fabric Native Component. diff --git a/docs/the-new-architecture/pillars-fabric-components.md b/docs/the-new-architecture/pillars-fabric-components.md index fa9fd98321c..8b4af25fad4 100644 --- a/docs/the-new-architecture/pillars-fabric-components.md +++ b/docs/the-new-architecture/pillars-fabric-components.md @@ -1,6 +1,6 @@ --- id: pillars-fabric-components -title: Fabric Components +title: Fabric Native Components --- import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; @@ -9,24 +9,24 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; -A Fabric Component is a UI component rendered on the screen using the [Fabric Renderer](https://reactnative.dev/architecture/fabric-renderer). Using Fabric Components instead of Native Components allows us to reap all the [benefits](./why) of the **New Architecture**: +A Fabric Native Component is a Native Component rendered on the screen using the [Fabric Renderer](https://reactnative.dev/architecture/fabric-renderer). Using Fabric Native Components instead of Legacy Native Components allows us to reap all the [benefits](./why) of the **New Architecture**: - Strongly typed interfaces that are consistent across platforms. - The ability to write your code in C++, either exclusively or integrated with another native platform language, hence reducing the need to duplicate implementations across platforms. - The use of JSI, a JavaScript interface for native code, which allows for more efficient communication between native and JavaScript code than the bridge. -A Fabric Component is created starting from a **JavaScript specification**. Then [**Codegen**](./pillars-codegen) creates some C++ scaffolding code to connect the component-specific logic (for example, accessing some native platform capability) to the rest of the React Native infrastructure. The C++ code is the same for all the platforms. Once the component is properly connected with the scaffolding code, it is ready to be imported and used by an app. +A Fabric Native Component is created starting from a **JavaScript specification**. Then [**Codegen**](./pillars-codegen) creates some C++ scaffolding code to connect the component-specific logic (for example, accessing some native platform capability) to the rest of the React Native infrastructure. The C++ code is the same for all the platforms. Once the component is properly connected with the scaffolding code, it is ready to be imported and used by an app. -The following section guides you through the creation of a Fabric Component, step-by-step, targeting React Native 0.70.0. +The following section guides you through the creation of a Fabric Native Component, step-by-step, targeting React Native 0.70.0. :::caution -Fabric Components only works with the **New Architecture** enabled. +Fabric Native Components only works with the **New Architecture** enabled. To migrate to the **New Architecture**, follow the [Migration guide](../new-architecture-intro) ::: -## How to Create a Fabric Components +## How to Create a Fabric Native Components -To create a Fabric Component, you have to follow these steps: +To create a Fabric Native Component, you have to follow these steps: 1. Define a set of JavaScript specifications. 2. Configure the component so that **Codegen** can create the shared code and it can be added as a dependency for an app. @@ -36,9 +36,9 @@ Once these steps are done, the component is ready to be consumed by an app. The ## 1. Folder Setup -In order to keep the component decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Fabric Component that can be released as open-source libraries later. +In order to keep the component decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Fabric Native Component that can be released as open-source libraries later. -For this guide, you are going to create a Fabric Component that centers some text on the screen. +For this guide, you are going to create a Fabric Native Component that centers some text on the screen. Create a new folder at the same level of the app and call it `RTNCenteredText`. @@ -108,7 +108,7 @@ export default codegenNativeComponent( -At the beginning of the spec files, there are the imports. The most important imports, required by every Fabric Component are: +At the beginning of the spec files, there are the imports. The most important imports, required by every Fabric Native Component are: - The `HostComponent`: type the exported component needs to conform to. - The `codegenNativeComponent` function: responsible to actually register the component in the JavaScript runtime. @@ -119,7 +119,7 @@ Finally, the spec file exports the returned value of the `codegenNativeComponent :::caution The JavaScript files imports types from libraries, without setting up a proper node module and installing its dependencies. The outcome of this is that the IDE may have troubles resolving the import statements and it can output errors and warnings. -These will disappear as soon as the Fabric Component is added as a dependency of a React Native app. +These will disappear as soon as the Fabric Native Component is added as a dependency of a React Native app. ::: ## 3. Component Configuration @@ -136,7 +136,7 @@ The shared configuration is a `package.json` file that will be used by yarn when { "name": "rtn-centered-text", "version": "0.0.1", - "description": "Showcase a Fabric Component with a centered text", + "description": "Showcase a Fabric Native Component with a centered text", "react-native": "js/index", "source": "js/index", "files": [ @@ -178,7 +178,7 @@ Then there are the dependencies for this package. For this guide, you need `reac Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a Fabric Component, thus the value to use is `components`. +- `type`: The type of module contained by this package. In this case, it is a Fabric Native Component, thus the value to use is `components`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. ### iOS: Create the `.podspec` file @@ -350,7 +350,7 @@ The last step requires you to write some native code to connect the JavaScript s 1. Run **Codegen** to see what would be generated. 2. Write the native code that will make it work. -When developing a React Native app that uses a Fabric Component, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a Fabric Component as a library, it needs to reference the generated code, and it is useful to see what the app will generate. +When developing a React Native app that uses a Fabric Native Component, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a Fabric Component as a library, it needs to reference the generated code, and it is useful to see what the app will generate. As the first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](./pillars-codegen.md). @@ -456,11 +456,11 @@ RCT_EXPORT_VIEW_PROPERTY(text, NSString) @end ``` -This file is the manager for the Fabric Component. React Native runtime uses manager objects to register the modules, properties and methods to make them available to the JavaScript side. +This file is the manager for the Fabric Native Component. React Native runtime uses manager objects to register the modules, properties and methods to make them available to the JavaScript side. The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that Fabric can retrieve and instantiate it. -Then, you have to expose the `text` property for the Fabric Component. This is done with the `RCT_EXPORT_VIEW_PROPERTY` macro, specifying a name and a type. +Then, you have to expose the `text` property for the Fabric Native Component. This is done with the `RCT_EXPORT_VIEW_PROPERTY` macro, specifying a name and a type. :::info There are other macros that can be used to export custom properties, emitters, and other constructs. You can view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Views/RCTViewManager.h). @@ -567,7 +567,7 @@ The component has to conform to a specific protocol generated by **Codegen**, in Then, the file defines a static `(ComponentDescriptorProvider)componentDescriptorProvider` method which Fabric uses to retrieve the descriptor provider to instantiate the object. -Then, there is the constructor of the view: the `init` method. In this method, it is important to create a `defaultProps` struct using the `RTNCenteredTextProps` type from **Codegen**. You need to assign it to the private `_props` to initialize the Fabric Component correctly. The remaining part of the initializer is standard Objective-C code to create views and layout them with AutoLayout. +Then, there is the constructor of the view: the `init` method. In this method, it is important to create a `defaultProps` struct using the `RTNCenteredTextProps` type from **Codegen**. You need to assign it to the private `_props` to initialize the Fabric Native Component correctly. The remaining part of the initializer is standard Objective-C code to create views and layout them with AutoLayout. The last two pieces are the `updateProps` method and the `RTNCenteredTextCls` method. @@ -576,7 +576,7 @@ The `updateProps` method is invoked by Fabric every time a prop changes in JavaS Finally, the `RTNCenteredTextCls` is another static method used to retrieve the correct instance of the class at runtime. :::caution -Differently from Native Components, Fabric requires to manually implement the `updateProps` method. It's not enough to export properties with the `RCT_EXPORT_XXX` and `RCT_REMAP_XXX` macros. +Differently from Legacy Native Components, Fabric requires to manually implement the `updateProps` method. It's not enough to export properties with the `RCT_EXPORT_XXX` and `RCT_REMAP_XXX` macros. ::: ### Android @@ -630,13 +630,13 @@ codegen └── schema.json ``` -You can see that the content of the `codegen/jni/react/renderer/components/RTNCenteredTextSpecs` looks similar to the files created by the iOS counterpart. The `Android.mk` and `CMakeList.txt` files configure the Fabric Component in the app, while the `RTNCenteredTextManagerDelegate.java` and `RTNCenteredTextManagerInterface.java` files are meant use in your manager. +You can see that the content of the `codegen/jni/react/renderer/components/RTNCenteredTextSpecs` looks similar to the files created by the iOS counterpart. The `Android.mk` and `CMakeList.txt` files configure the Fabric Native Component in the app, while the `RTNCenteredTextManagerDelegate.java` and `RTNCenteredTextManagerInterface.java` files are meant use in your manager. See the [Codegen](./pillars-codegen) section for further details on the generated files. #### Write the Native Android Code -The native code for the Android side of a Fabric Components requires three pieces: +The native code for the Android side of a Fabric Native Components requires three pieces: 1. A `RTNCenteredText.java` that represents the actual view. 2. A `RTNCenteredTextManager.java` to instantiate the view. @@ -788,11 +788,11 @@ public class RTNCenteredTextPackage implements ReactPackage { } ``` -The added lines instantiate a new `RTNCenteredTextManager` object so that the React Native runtime can use it to render our Fabric Component. +The added lines instantiate a new `RTNCenteredTextManager` object so that the React Native runtime can use it to render our Fabric Native Component. -## 5. Adding the Fabric Component To Your App +## 5. Adding the Fabric Native Component To Your App -This is the last step to finally see your Fabric Component running on your app. +This is the last step to finally see your Fabric Native Component running on your app. ### Shared diff --git a/docs/the-new-architecture/pillars-turbomodule.md b/docs/the-new-architecture/pillars-turbomodule.md index 9452acaf086..29f8c2a775a 100644 --- a/docs/the-new-architecture/pillars-turbomodule.md +++ b/docs/the-new-architecture/pillars-turbomodule.md @@ -1,6 +1,6 @@ --- id: pillars-turbomodules -title: TurboModules +title: Turbo Native Modules --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; @@ -10,23 +10,23 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; If you've worked with React Native, you may be familiar with the concept of [Native Modules](../native-modules-intro.md), which allow JavaScript and platform-native code to communicate over the React Native "bridge", which handles cross-platform serialization via JSON. -TurboModules are the next iteration on Native Modules that provide a few extra [benefits](./why): +Turbo Native Modules are the next iteration on Native Modules that provide a few extra [benefits](./why): - Strongly typed interfaces that are consistent across platforms - The ability to write your code in C++, either exclusively or integrated with another native platform language, reducing the need to duplicate implementations across platforms - Lazy loading of modules, allowing for faster app startup - The use of JSI, a JavaScript interface for native code, allows for more efficient communication between native and JavaScript code than the bridge -This guide will show you how to create a basic TurboModule compatible with React Native 0.70.0. +This guide will show you how to create a basic Turbo Native Module compatible with React Native 0.70.0. :::caution -TurboModules only work with the **New Architecture** enabled. +Turbo Native Modules only work with the **New Architecture** enabled. To migrate to the **New Architecture**, follow the [Migration guide](../new-architecture-intro) ::: -## How to Create a TurboModule +## How to Create a Turbo Native Module -To create a TurboModule, we need to: +To create a Turbo Native Module, we need to: 1. Define the JavaScript specification. 2. Configure the module so that Codegen can generate the scaffolding. @@ -34,7 +34,7 @@ To create a TurboModule, we need to: ## 1. Folder Setup -In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing TurboModules that can be released as open-source libraries later. +In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Turbo Native Modules that can be released as open-source libraries later. Next to your application, create a folder called `RTNCalculator`. **RTN** stands for "**R**eac**t** **N**ative", and is a recommended prefix for React Native modules. @@ -97,12 +97,12 @@ export default TurboModuleRegistry.get( At the beginning of the spec files are the imports: -- The `TurboModule` type, which defines the base interface for all TurboModules -- The `TurboModuleRegistry` JavaScript module, which contains functions for loading TurboModules +- The `TurboModule` type, which defines the base interface for all Turbo Native Modules +- The `TurboModuleRegistry` JavaScript module, which contains functions for loading Turbo Native Modules -The second section of the file contains the interface specification for the TurboModule. In this case, the interface defines the `add` function, which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a TurboModule. +The second section of the file contains the interface specification for the Turbo Native Module. In this case, the interface defines the `add` function, which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a Turbo Native Module. -Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the TurboModule if it's available. +Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the Turbo Native Module if it's available. :::caution We are writing JavaScript files importing types from libraries, without setting up a proper node module and installing its dependencies. Your IDE will not be able to resolve the import statements and you may see errors and warnings. This is expected and will not cause problems when you add the module to your app. @@ -122,7 +122,7 @@ The shared configuration is a `package.json` file used by yarn when installing y { "name": "rtn-calculator", "version": "0.0.1", - "description": "Add numbers with TurboModules", + "description": "Add numbers with Turbo Native Modules", "react-native": "js/index", "source": "js/index", "files": [ @@ -167,7 +167,7 @@ Then there are the dependencies for this package. For this guide, you need `reac Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a TurboModule; thus, the value to use is `modules`. +- `type`: The type of module contained by this package. In this case, it is a Turbo Native Module; thus, the value to use is `modules`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. - `android.javaPackageName`: the package to use in the Java files generated by **Codegen**. @@ -329,12 +329,12 @@ React Native uses the `ReactPackage` interface to understand what native classes ## 4. Native Code -For the final step in getting your TurboModule ready to go, you'll need to write some native code to connect the JavaScript side to the native platforms. This process requires two main steps: +For the final step in getting your Turbo Native Module ready to go, you'll need to write some native code to connect the JavaScript side to the native platforms. This process requires two main steps: - Run **Codegen** to see what it generates. - Write your native code, implementing the generated interfaces. -When developing a React Native app that uses a TurboModule, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore, useful to see what the app will generate. +When developing a React Native app that uses a Turbo Native Module, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore, useful to see what the app will generate. As the first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](pillars-codegen.md). @@ -390,7 +390,7 @@ generated └── ShadowNodes.h ``` -The relevant path for the TurboModule interface is `generated/build/generated/ios/RTNCalculatorSpec`. +The relevant path for the Turbo Native Module interface is `generated/build/generated/ios/RTNCalculatorSpec`. See the [Codegen](./pillars-codegen) section for further details on the generated files. @@ -407,7 +407,7 @@ rm -rf build #### Write the Native iOS Code -Now add the Native code for your TurboModule. Create two files in the `RTNCalculator/ios` folder: +Now add the Native code for your Turbo Native Module. Create two files in the `RTNCalculator/ios` folder: 1. The `RTNCalculator.h`, a header file for the module. 2. The `RTNCalculator.mm`, the implementation of the module. @@ -456,11 +456,11 @@ RCT_REMAP_METHOD(add, addA:(NSInteger)a @end ``` -The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that React Native can load the TurboModule. +The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that React Native can load the Turbo Native Module. Then the `RCT_REMAP_METHOD` macro is used to expose the `add` method. -Finally, the `getTurboModule` method gets an instance of the TurboModule so that the JavaScript side can invoke its methods. The function is defined in (and requested by) the `RTNCalculatorSpec.h` file that was generated earlier by Codegen. +Finally, the `getTurboModule` method gets an instance of the Turbo Native Module so that the JavaScript side can invoke its methods. The function is defined in (and requested by) the `RTNCalculatorSpec.h` file that was generated earlier by Codegen. :::info There are other macros that can be used to export modules and methods. You view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Base/RCTBridgeModule.h). @@ -516,7 +516,7 @@ codegen #### Write the Native Android Code -The native code for the Android side of a TurboModule requires: +The native code for the Android side of a Turbo Native Module requires: 1. to create a `RTNCalculatorModule.java` that implements the module. 2. to update the `RTNCalculatorPackage.java` created in the previous step. @@ -628,9 +628,9 @@ public class CalculatorPackage extends TurboReactPackage { This is the last piece of Native Code for Android. It defines the `TurboReactPackage` object that will be used by the app to load the module. -## 5. Adding the TurboModule to your App +## 5. Adding the Turbo Native Module to your App -Now you can install and use the TurboModule in your app. +Now you can install and use the Turbo Native Module in your app. ### Shared @@ -667,7 +667,7 @@ Android configuration requires to enable the **New Architecture**: ### JavaScript -Now you can use your TurboModule calculator in your app! +Now you can use your Turbo Native Module calculator in your app! Here's an example App.js file using the `add` method: @@ -711,4 +711,4 @@ const App: () => Node = () => { export default App; ``` -Try this out to see your TurboModule in action! +Try this out to see your Turbo Native Module in action! diff --git a/docs/the-new-architecture/pillars.md b/docs/the-new-architecture/pillars.md index 05a828af51c..14fd75eb8cf 100644 --- a/docs/the-new-architecture/pillars.md +++ b/docs/the-new-architecture/pillars.md @@ -9,12 +9,19 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; The New Architecture is composed mainly of two pillars: -- [TurboModules](pillars-turbomodules) -- [Fabric Components](pillars-fabric-components). +- [The New Native Module System - Turbo Modules](pillars-turbomodules) +- [The New Renderer - Fabric](pillars-fabric-components). -TurboModules are the preferred way to create libraries that leverage some platform-specific API. Fabric Components are the preferred way to create reusable UI components, providing a native experience to the users. +The core concepts of React Native still holds true in the New Architecture: Native Modules are the preferred way to create libraries that leverage some platform-specific API. Native Components are the preferred way to create reusable UI components, providing a native experience to the users. -The main goal of this section is to drive the reader through a step-by-step guide to create their first TurboModule or Fabric Component. +The main goal of this section is to drive the reader through a step-by-step guide to create their first Native Module or Component which is compatible with the New Architecture. + +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Components** & **Legacy Native Modules** - To refer to Modules and Components which are running on the old React Native architecture. +- **Fabric Native Components** & **Turbo Native Modules** - To refer to Modules and Components which have been adapted to work well with the New Architecture, namely the new renderer and the new Native Module System. For brevity you might find them referred as **Fabric Components** and **Turbo Modules** + ::: The next sections contain a high-level overview of the pillars and the steps to create them. To create one of these pillars, the steps are: @@ -26,7 +33,7 @@ The next sections contain a high-level overview of the pillars and the steps to Finally, we dive a little deeper into the [Codegen](pillars-codegen) process that is required to create all the C++ types and files used by our components, including some useful steps to work comfortably while developing the component. :::caution -The app has to run with the **New Architecture enabled to integrate a TurboModule or a Fabric Component** in an app. +The app has to run with the **New Architecture enabled to integrate a Turbo Native Module or a Fabric Native Component** in an app. To create a new app adopting the New Architecture, refer to the [Using the App Template](use-app-template) section. To migrate an existing app to the New Architecture, refer to the [Migration](../new-architecture-intro) guide. diff --git a/docs/the-new-architecture/use-app-template.md b/docs/the-new-architecture/use-app-template.md index 8abd06fb9a8..53f96acc3f6 100644 --- a/docs/the-new-architecture/use-app-template.md +++ b/docs/the-new-architecture/use-app-template.md @@ -123,8 +123,8 @@ For further explanations of what each file is doing, check out these guides to w #### Android -- [Enabling TurboModules on Android](new-architecture-app-modules-android.md) -- [Enabling Fabric on Android](new-architecture-app-renderer-android.md) +- [Enabling the New Native Module System (Turbo Module) on Android](new-architecture-app-modules-android.md) +- [Enabling the New Renderer (Fabric) on Android](new-architecture-app-renderer-android.md) #### iOS diff --git a/docs/the-new-architecture/why.md b/docs/the-new-architecture/why.md index 84b8fe62e0e..964cfb0e9ef 100644 --- a/docs/the-new-architecture/why.md +++ b/docs/the-new-architecture/why.md @@ -35,7 +35,7 @@ This idea allowed the unlocking of several benefits: - **Code sharing:** by introducing C++, it is now possible to abstract all the platform agnostic code and to share it with ease between the platforms. - **Type safety:** to make sure that JS can properly invoke methods on C++ objects and vice-versa, a layer of code automatically generated has been added. The code is generated starting from some JS specification that must be typed through Flow or TypeScript. -These advantages are the foundations of the [TurboModule](pillars-turbomodules) system and a jumping stone to further enhancements. For example, it has been possible to develop a new renderer that is faster and more performant: [Fabric](/architecture/fabric-renderer) and its [Fabric Components](pillars-fabric-components). +These advantages are the foundations of the [New Native Module System](pillars-turbomodules) and a jumping stone to further enhancements. For example, it has been possible to develop a [new renderer](/architecture/fabric-renderer) which offers faster and more performant [Native Components](pillars-fabric-components). ## Further Reading From bbd36d157cedab6517a62c4bfdd1cdf94b8aa432 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 9 Sep 2022 21:18:24 +0100 Subject: [PATCH 20/88] [0.70] Clarify New Architecture Terminology (#3315) --- .../new-architecture-app-intro.md | 2 +- .../new-architecture-app-modules-android.md | 10 ++-- .../new-architecture-app-modules-ios.md | 10 ++-- .../new-architecture-app-renderer-android.md | 10 ++-- .../version-0.70/new-architecture-appendix.md | 17 +++++-- .../version-0.70/new-architecture-intro.md | 4 +- .../new-architecture-library-intro.md | 6 +-- .../new-architecture-library-ios.md | 2 +- .../version-0.70/react-18-and-react-native.md | 2 +- .../_markdown_native_deprecation.mdx | 2 +- ...ackward-compatibility-fabric-components.md | 47 ++++++++++-------- .../backward-compatibility-turbomodules.md | 47 +++++++++++------- .../backward-compatibility.md | 6 +-- .../the-new-architecture/landing-page.md | 6 +-- .../the-new-architecture/pillars-codegen.md | 42 ++++++++-------- .../pillars-fabric-components.md | 20 ++++---- .../pillars-turbomodule.md | 48 +++++++++---------- .../the-new-architecture/pillars.md | 19 ++++++-- .../the-new-architecture/use-app-template.md | 8 ++-- .../version-0.70/the-new-architecture/why.md | 2 +- 20 files changed, 174 insertions(+), 136 deletions(-) diff --git a/website/versioned_docs/version-0.70/new-architecture-app-intro.md b/website/versioned_docs/version-0.70/new-architecture-app-intro.md index b0b0b519a60..5b38ab5073e 100644 --- a/website/versioned_docs/version-0.70/new-architecture-app-intro.md +++ b/website/versioned_docs/version-0.70/new-architecture-app-intro.md @@ -226,7 +226,7 @@ React Native supports also a local version of this file `.xcode.env.local`. This ## iOS: Use Objective-C++ (`.mm` extension) -TurboModules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. +Turbo Native Modules can be written using Objective-C or C++. In order to support both cases, any source files that include C++ code should use the `.mm` file extension. This extension corresponds to Objective-C++, a language variant that allows for the use of a combination of C++ and Objective-C in source files. :::info diff --git a/website/versioned_docs/version-0.70/new-architecture-app-modules-android.md b/website/versioned_docs/version-0.70/new-architecture-app-modules-android.md index b3e8fddfb7c..02069ffac51 100644 --- a/website/versioned_docs/version-0.70/new-architecture-app-modules-android.md +++ b/website/versioned_docs/version-0.70/new-architecture-app-modules-android.md @@ -100,7 +100,7 @@ yarn react-native run-android ## 2. Java/Kotlin - Provide a `ReactPackageTurboModuleManagerDelegate` -Now is time to actually use the TurboModule. +Now is time to actually use the Turbo Native Module. First, we will need to create a `ReactPackageTurboModuleManagerDelegate` subclass, like the following: @@ -193,7 +193,7 @@ protected constructor( Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `project()` inside the `CMakeLists.txt` file you created before. -This class will then be responsible of loading the TurboModules and will take care of loading the native library build with the NDK at runtime. +This class will then be responsible of loading the Turbo Native Modules and will take care of loading the native library build with the NDK at runtime. ## 3. Adapt your `ReactNativeHost` to use the `ReactPackageTurboModuleManagerDelegate` @@ -259,7 +259,7 @@ class MyApplication : Application(), ReactApplication { ## 4. Extend the `getPackages()` from your `ReactNativeHost` to use the TurboModule -Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created TurboModule. Update the method to include the following: +Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created Turbo Native Module. Update the method to include the following: @@ -493,7 +493,7 @@ std::shared_ptr MyApplicationModuleProvider(const std::string modul Please adapt the `samplelibrary.h` import to match the same library name you provided when building the apps. This is the C++ generated file that is created by the codegen. -Here you can also specify more than one provider, should you have more than one TurboModule. Specifically in this example we look for a TurboModule from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). +Here you can also specify more than one provider, should you have more than one Turbo Native Module. Specifically in this example we look for a Turbo Native Module from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). ```cpp #include "MyApplicationModuleProvider.h" @@ -532,7 +532,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { ## 6. Enable the `useTurboModules` flag in your Application `onCreate` -Now you can finally enable the `TurboModule `support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. +Now you can finally enable the `Turbo Native Module` support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. diff --git a/website/versioned_docs/version-0.70/new-architecture-app-modules-ios.md b/website/versioned_docs/version-0.70/new-architecture-app-modules-ios.md index ca6f9306a1c..345171166fb 100644 --- a/website/versioned_docs/version-0.70/new-architecture-app-modules-ios.md +++ b/website/versioned_docs/version-0.70/new-architecture-app-modules-ios.md @@ -18,7 +18,7 @@ Add the following imports at the top of your bridge delegate (e.g. `AppDelegate. #import ``` -You will also need to declare that your AppDelegate conforms to the `RCTTurboModuleManagerDelegate` protocol, as well as create an instance variable for our Turbo Module manager: +You will also need to declare that your AppDelegate conforms to the `RCTTurboModuleManagerDelegate` protocol, as well as create an instance variable for our Turbo Native Module manager: ```objc @interface AppDelegate () { @@ -31,8 +31,8 @@ You will also need to declare that your AppDelegate conforms to the `RCTTurboMod To conform to the `RCTTurboModuleManagerDelegate` protocol, you will implement these three methods: - `getModuleClassFromName:` - This method should return the Class for a native module. You may use the `RCTCoreModulesClassProvider()` method to handle the default, core modules. -- `getTurboModule:jsInvoker:` - This should return `nullptr`. This method may be used later to support C++ TurboModules. -- `getModuleInstanceFromClass:moduleClass:` - This method allows you to perform any side-effects when your TurboModules are initialized. This is the TurboModule analogue to your bridge delegate’s `extraModulesForBridge` method. At this time, you’ll need to initialize the default RCTNetworking and RCTImageLoader modules as indicated below. +- `getTurboModule:jsInvoker:` - This should return `nullptr`. This method may be used later to support C++ Turbo Native Modules. +- `getModuleInstanceFromClass:moduleClass:` - This method allows you to perform any side-effects when your Turbo Native Modules are initialized. This is the Turbo Native Module analogue to your bridge delegate’s `extraModulesForBridge` method. At this time, you’ll need to initialize the default RCTNetworking and RCTImageLoader modules as indicated below. #### TurboModuleManagerDelegate Example @@ -147,9 +147,9 @@ Next, you will create a `RCTTurboModuleManager` in your bridge delegate’s `jsE } ``` -## 3. Enable TurboModule System +## 3. Enable Turbo Native Module System -Finally, enable TurboModules in your app by executing the following statement before React Native is initialized in your app delegate (e.g. within `didFinishLaunchingWithOptions:`): +Finally, enable Turbo Native Modules in your app by executing the following statement before React Native is initialized in your app delegate (e.g. within `didFinishLaunchingWithOptions:`): ```objc RCTEnableTurboModule(YES); diff --git a/website/versioned_docs/version-0.70/new-architecture-app-renderer-android.md b/website/versioned_docs/version-0.70/new-architecture-app-renderer-android.md index 736abcb8f56..8dce0ad936d 100644 --- a/website/versioned_docs/version-0.70/new-architecture-app-renderer-android.md +++ b/website/versioned_docs/version-0.70/new-architecture-app-renderer-android.md @@ -11,7 +11,7 @@ Make sure your application meets all the [prerequisites](new-architecture-app-in ## 1. Provide a `JSIModulePackage` inside your `ReactNativeHost` -In order to enable Fabric in your app, you would need to add a `JSIModulePackage` inside your `ReactNativeHost`. If you followed the TurboModule section of this guide, you probably already know where to find your `ReactNativeHost`. If not, you can locate your `ReactNativeHost` by searching for the `getReactNativeHost()`. The `ReactNativeHost` is usually located inside your `Application` class. +In order to enable Fabric in your app, you would need to add a `JSIModulePackage` inside your `ReactNativeHost`. If you followed the Turbo Native Module section of this guide, you probably already know where to find your `ReactNativeHost`. If not, you can locate your `ReactNativeHost` by searching for the `getReactNativeHost()`. The `ReactNativeHost` is usually located inside your `Application` class. Once you located it, you need to add the `getJSIModulePackage` method as from the snippet below: @@ -113,12 +113,12 @@ LOG Running "App" with {"fabric":true,"initialProps":{},"rootTag":1} ## Migrating Android ViewManagers -First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (TurboModule) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. +First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New Native Module System (Turbo Module) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. ### JavaScript changes 1. Make sure your other JS changes are ready to go by following Preparing your JavaScript codebase for the new React Native Renderer (Fabric) -2. Replace the call to `requireNativeComponent` with `codegenNativeComponent`. This tells the JS codegen to start generating the native implementation of the component, consisting of C++ and Java classes. This is how it looks for the WebView component: +2. Replace the call to `requireNativeComponent` with `codegenNativeComponent`. This tells the JS codegen to start generating the native implementation of the Native Component, consisting of C++ and Java classes. This is how it looks for the WebView component: ```ts import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; @@ -131,7 +131,7 @@ export default (codegenNativeComponent( ): HostComponent); ``` -4. **[Flow users]** Make sure your native component has Flow types for its props, since the JS codegen uses these types to generate the type-safe native implementation of the component. The codegen generates C++ classes during the build time, which guarantees that the native implementation is always up-to-date with its JS interface. Use [these c++ compatible types](https://github.com/facebook/react-native/blob/main/Libraries/Types/CodegenTypes.js#L28-L30). +4. **[Flow users]** Make sure your Native Component has Flow types for its props, since the JS codegen uses these types to generate the type-safe native implementation of the Component. The codegen generates C++ classes during the build time, which guarantees that the native implementation is always up-to-date with its JS interface. Use [these c++ compatible types](https://github.com/facebook/react-native/blob/main/Libraries/Types/CodegenTypes.js#L28-L30). ```ts title="RNTMyNativeViewNativeComponent.js" import type {Int32} from 'react-native/Libraries/Types/CodegenTypes'; @@ -428,7 +428,7 @@ void MyComponentsRegistry::registerNatives() { 4. **Load your file in the OnLoad.cpp** -If you followed the TurboModule instructions, you should have a `OnLoad.cpp` file inside the `src/main/jni` folder. There you should add a line to load the `MyComponentsRegistry` class: +If you followed the Turbo Native Module instructions, you should have a `OnLoad.cpp` file inside the `src/main/jni` folder. There you should add a line to load the `MyComponentsRegistry` class: ```cpp title="OnLoad.cpp" #include diff --git a/website/versioned_docs/version-0.70/new-architecture-appendix.md b/website/versioned_docs/version-0.70/new-architecture-appendix.md index 56b3301423b..61bbc1377e3 100644 --- a/website/versioned_docs/version-0.70/new-architecture-appendix.md +++ b/website/versioned_docs/version-0.70/new-architecture-appendix.md @@ -7,7 +7,16 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; -## I. Flow Type to Native Type Mapping +## I. Terminology + +The whole New Architecture related guides will stick to the following **terminology**: + +- **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. +- **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. +- **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Architecture, namely the new renderer. For brevity you might find them referred as **Fabric Components**. +- **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Architecture, namely the new Native Module System. For brevity you might find them referred as **Turbo Modules** + +## II. Flow Type to Native Type Mapping You may use the following table as a reference for which types are supported and what they map to in each platform: @@ -85,7 +94,7 @@ Callback functions are not type checked, and are generalized as `Object`s. You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository. ::: -## II. TypeScript to Native Type Mapping +## III. TypeScript to Native Type Mapping You may use the following table as a reference for which types are supported and what they map to in each platform: @@ -105,7 +114,7 @@ You may use the following table as a reference for which types are supported and You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository. -## III. Invoking the code-gen during development +## IV. Invoking the code-gen during development > This section contains information specific to v0.66 of React Native. @@ -182,7 +191,7 @@ node node_modules/react-native/scripts/generate-specs-cli.js \ In the above example, the code-gen script will generate several files: `MyLibSpecs.h` and `MyLibSpecs-generated.mm`, as well as a handful of `.h` and `.cpp` files, all located in the `ios` directory. -## IV. Note on Existing Apps +## V. Note on Existing Apps This guide provides instructions for migrating an application that is based on the default app template that is provided by React Native. If your app has deviated from the template, or you are working with an application that was never based off the template, then the following sections might help. diff --git a/website/versioned_docs/version-0.70/new-architecture-intro.md b/website/versioned_docs/version-0.70/new-architecture-intro.md index fa88aeb9e8d..511c4053fd1 100644 --- a/website/versioned_docs/version-0.70/new-architecture-intro.md +++ b/website/versioned_docs/version-0.70/new-architecture-intro.md @@ -9,7 +9,7 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; # Getting Started with the New Architecture -This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **new NativeModule system (TurboModule) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps. +This migration guide is designed for React Native **library authors** and **application developers**. It outlines the steps you need to follow to roll out the new Architecture, composed by the **New Native Module system (Turbo Module) and the new Renderer (Fabric)** to your **Android** and **iOS** libraries and apps. ## Table of Contents @@ -22,7 +22,7 @@ The guide is divided into five sections: - [iOS](new-architecture-library-ios) - **Supporting the New Architecture in your App** - [Prerequisites for Supporting the New Architecture in your App](new-architecture-app-intro) - - Enabling the New NativeModule System (TurboModule) in your App + - Enabling the New Native Module System (Turbo Module) in your App - [Android](new-architecture-app-modules-android) - [iOS](new-architecture-app-modules-ios) - Enabling the New Renderer (Fabric) in your App diff --git a/website/versioned_docs/version-0.70/new-architecture-library-intro.md b/website/versioned_docs/version-0.70/new-architecture-library-intro.md index b0eaaca055a..ae5a05371e7 100644 --- a/website/versioned_docs/version-0.70/new-architecture-library-intro.md +++ b/website/versioned_docs/version-0.70/new-architecture-library-intro.md @@ -23,7 +23,7 @@ Currently, this guide is written under the assumption that you will be using [Fl To adopt the New Architecture, you start by creating these specs for your native modules and native components. You can do this prior to actually migrating to the New Architecture: the specs will be used later on to generate native interface code for all the supported platforms, as a way to enforce uniform APIs across platforms. -#### Turbomodules +#### Turbo Native Modules JavaScript spec files **must** be named `Native.js` and they export a `TurboModuleRegistry` `Spec` object. The name convention is important because the Codegen process looks for modules whose `js` (`jsx`, `ts`, or `tsx`) spec file starts with the keyword `Native`. @@ -70,7 +70,7 @@ export default TurboModuleRegistry.get(''); -#### Fabric Components +#### Fabric Native Components JavaScript spec files **must** be named `NativeComponent.js` (for TypeScript use extension `.ts` or `.tsx`) and they export a `HostComponent` object. The name convention is important: the Codegen process looks for components whose spec file (either JavaScript or TypeScript) ends with the suffix `NativeComponent`. @@ -214,7 +214,7 @@ Codegen can be configured in the `package.json` file of your Library. Add the fo - The `codegenConfig` is the key used by the Codegen to verify that there is some code to generate. - The `name` field, is the name of the library. -- The `type` field is used to identify the type of module we want to create. Our suggestions is to keep `all` to support libraries that contains both TurboModule and Fabric Components. +- The `type` field is used to identify the type of module we want to create. Our suggestion is to keep `all` to support libraries that contain both Turbo Native Module and Fabric Native Components. - The `jsSrcsDir` is the directory where the codegen will start looking for JavaScript specs. - The `android.javaPackageName` is the name of the package where the generated code wil end up. diff --git a/website/versioned_docs/version-0.70/new-architecture-library-ios.md b/website/versioned_docs/version-0.70/new-architecture-library-ios.md index c5054bd6e8e..6b6955ff020 100644 --- a/website/versioned_docs/version-0.70/new-architecture-library-ios.md +++ b/website/versioned_docs/version-0.70/new-architecture-library-ios.md @@ -32,7 +32,7 @@ Pod::Spec.new do |s| } s.dependency "React-Core" - s.dependency "React-RCTFabric" # This is for Fabric Component + s.dependency "React-RCTFabric" # This is for Fabric Native Component s.dependency "React-Codegen" s.dependency "RCT-Folly" s.dependency "RCTRequired" diff --git a/website/versioned_docs/version-0.70/react-18-and-react-native.md b/website/versioned_docs/version-0.70/react-18-and-react-native.md index ed4a5d09eb6..33892b9e1d6 100644 --- a/website/versioned_docs/version-0.70/react-18-and-react-native.md +++ b/website/versioned_docs/version-0.70/react-18-and-react-native.md @@ -31,7 +31,7 @@ The concurrent features in React 18 are built on top of the new concurrent rende Previous versions of React Native built on the old architecture **cannot** support concurrent rendering or concurrent features. This is because the old architecture relied on mutating the native trees, which doesn’t allow for React to prepare multiple versions of the tree at the same time. -Fortunately, the New Architecture was written bottom-up with concurrent rendering in mind, and is fully compatible with React 18. This means, in order to upgrade to React 18 in your React Native app, your application needs to be migrated to the React Native's New Architecture including Fabric and TurboModules. +Fortunately, the New Architecture was written bottom-up with concurrent rendering in mind, and is fully compatible with React 18. This means, in order to upgrade to React 18 in your React Native app, your application needs to be migrated to the React Native's New Architecture including Fabric Native Components and Turbo Native Modules. ## React 18 enabled by default diff --git a/website/versioned_docs/version-0.70/the-new-architecture/_markdown_native_deprecation.mdx b/website/versioned_docs/version-0.70/the-new-architecture/_markdown_native_deprecation.mdx index 569a078d147..390bfcdc3de 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/_markdown_native_deprecation.mdx +++ b/website/versioned_docs/version-0.70/the-new-architecture/_markdown_native_deprecation.mdx @@ -1,4 +1,4 @@ :::info Native Module and Native Components are our stable technologies used by the legacy architecture. -They will be deprecated in the future when the New Architecture will be stable. The New Architecture uses [TurboModule](./the-new-architecture/pillars-turbomodules) and [Fabric Components](./the-new-architecture/pillars-fabric-components) to achieve similar results. +They will be deprecated in the future when the New Architecture will be stable. The New Architecture uses [Turbo Native Module](./the-new-architecture/pillars-turbomodules) and [Fabric Native Components](./the-new-architecture/pillars-fabric-components) to achieve similar results. ::: diff --git a/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility-fabric-components.md b/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility-fabric-components.md index 8226a24730f..8ddb0d036d8 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility-fabric-components.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility-fabric-components.md @@ -1,6 +1,6 @@ --- id: backward-compatibility-fabric-components -title: Fabric Components as Native Components +title: Fabric Components as Legacy Native Components --- import Tabs from '@theme/Tabs'; @@ -12,28 +12,35 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -The creation of a backward compatible Fabric Component requires the knowledge of how to create a Fabric Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). +Creating a backward compatible Fabric Native Component requires the knowledge of how to create a Legacy Native Component. To recall these concepts, have a look at this [guide](pillars-fabric-components). -Fabric Components only work when the New Architecture is properly setup. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. +Fabric Native Components only work when the New Architecture is properly set up. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: -Creating a backward compatible Fabric Component lets your users continue leverage your library, independently from the architecture they use. The creation of such a component requires a few steps: +Creating a backward compatible Fabric Native Component lets your users continue to leverage your library independently from the architecture they use. The creation of such a component requires a few steps: 1. Configure the library so that dependencies are prepared set up properly for both the Old and the New Architecture. 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. +- **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Native Renderer, Fabric. For brevity you might find them referred as **Fabric Components**. + ::: + While the last step is the same for all the platforms, the first two steps are different for iOS and Android. -## Configure the Fabric Component Dependencies +## Configure the Fabric Native Component Dependencies ### iOS -The Apple platform installs Fabric Components using [Cocoapods](https://cocoapods.org) as dependency manager. +The Apple platform installs Fabric Native Components using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every Fabric Component defines a `podspec` that looks like this: +Every Fabric Native Component defines a `podspec` that looks like this: ```ruby require "json" @@ -104,13 +111,13 @@ This `if` guard prevents the dependencies from being installed when the environm ### Android -To create a module that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. +To create a Native Component that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. :::note Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure the maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: -To configure the Fabric Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: +To configure the Fabric Native Component so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: ```diff title="build.gradle" +// Add this function in case you don't have it already @@ -148,7 +155,7 @@ This changes do three main things: The second step is to instruct Xcode to avoid compiling all the lines using the New Architecture types and files when we are building an app with the Old Architecture. -A Fabric Component requires an header file and an implementation file to add the actual `View` to the module. +A Fabric Native Component requires an header file and an implementation file to add the actual `View` to the module. For example, the `RNMyComponentView.h` header file could look like this: @@ -236,15 +243,15 @@ As we can't use conditional compilation blocks on Android, we will define two di Therefore, you have to: -1. Create a Native Component in the `src/oldarch` path. See [this guide](../native-components-android) to learn how to create a Native Component. -2. Create a Fabric Component in the `src/newarch` path. See [this guide](pillars-fabric-components) to learn how to create a Fabric Component. +1. Create a Legacy Native Component in the `src/oldarch` path. See [this guide](../native-components-android) to learn how to create a Legacy Native Component. +2. Create a Fabric Native Component in the `src/newarch` path. See [this guide](pillars-fabric-components) to learn how to create a Fabric Native Component. and then instruct Gradle to decide which implementation to pick. -Some files can be shared between a Native and a Fabric Component: these should be created or moved into a folder that is loaded by both the architectures. These files are: +Some files can be shared between a Legacy and a Fabric Component: these should be created or moved into a folder that is loaded by both the architectures. These files are: - the `.java` that instantiate and configure the Android View for both the components. -- the `ManagerImpl.java` file where which contains the logic of the ViewManager that can be shared between the Native and the Fabric Component. +- the `ManagerImpl.java` file where which contains the logic of the ViewManager that can be shared between the Legacy and the Fabric Component. - the `Package.java` file used to load the component. The final folder structure looks like this: @@ -275,7 +282,7 @@ my-component └── package.json ``` -The code that should go in the `MyComponentViewManagerImpl.java` and that can be shared between the Native Component and the Fabric Component is, for example: +The code that should go in the `MyComponentViewManagerImpl.java` and that can be shared between the Native Component and the Fabric Native Component is, for example: ```java title="example of MyComponentViewManager.java" package com.MyComponent; @@ -296,7 +303,7 @@ public class MyComponentViewManagerImpl { } ``` -Then, the Native Component and the Fabric Component can be updated using the function declared in the shared manager. +Then, the Native Component and the Fabric Native Component can be updated using the function declared in the shared manager. For example, for a Native Component: @@ -330,7 +337,7 @@ public class MyComponentViewManager extends SimpleViewManager { } ``` -And, for a Fabric Component: +And, for a Fabric Native Component: ```java title="Fabric Component using the ViewManagerImpl" // Use the static NAME property from the shared implementation @@ -381,7 +388,7 @@ For a step-by-step example on how to achieve this, have a look at [this repo](ht The last step makes sure that the JavaScript behaves transparently to chosen architecture. -For a Fabric Component, the source of truth is the `NativeComponent.js` (or `.ts`) spec file. The app accesses the spec file like this: +For a Fabric Native Component, the source of truth is the `NativeComponent.js` (or `.ts`) spec file. The app accesses the spec file like this: ```ts import MyComponent from 'your-component/src/index'; @@ -431,5 +438,5 @@ Whether you are using Flow or TypeScript for your specs, we understand which arc Please note that the New Architecture is still experimental. The `global.nativeFabricUIManager` API might change in the future for a function that encapsulate this check. ::: -- If that object is `null`, the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). -- If that object is set, the app is running with Fabric enabled and it should use the `NativeComponent` spec to access the Fabric Component. +- If that object is `null`, then the app has not enabled the Fabric feature. It's running on the Old Architecture, and the fallback is to use the default Legacy Native Components implementation ([iOS](../native-components-ios) or [Android](../native-components-android)). +- If that object is set, the app is running with Fabric enabled, and it should use the `NativeComponent` spec to access the Fabric Native Component. diff --git a/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility-turbomodules.md b/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility-turbomodules.md index 42d8a1cbc87..032e2328de4 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility-turbomodules.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility-turbomodules.md @@ -1,6 +1,6 @@ --- id: backward-compatibility-turbomodules -title: TurboModules as Native Modules +title: Turbo Modules as Legacy Native Modules --- import Tabs from '@theme/Tabs'; @@ -12,7 +12,7 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; :::info -The creation of a backward compatible TurboModule requires the knowledge of how to create a TurboModule. To recall these concepts, have a look at this [guide](pillars-turbomodules). +Creating a backward compatible Turbo Native Module requires the knowledge of how to create a Legacy Native Module. To recall these concepts, have a look at this [guide](pillars-turbomodules). TurboModules only works when the New Architecture is properly setup. If you already have a library that you want to migrate to the New Architecture, have a look at the [migration guide](../new-architecture-intro) as well. ::: @@ -23,11 +23,24 @@ Creating a backward compatible TurboModule lets your users continue leverage you 1. Update the codebase so that the New Architecture types are not compiled when not available. 1. Uniform the JavaScript API so that your user code won't need changes. +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. +- **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Native Module System. For brevity you might find them referred as **Turbo Modules**. + ::: + While the last step is the same for all the platforms, the first two steps are different for iOS and Android. -## Configure the TurboModule Dependencies +## Configure the Turbo Native Module Dependencies + +### iOS + +The Apple platform installs Turbo Native Modules using [Cocoapods](https://cocoapods.org) as a dependency manager. + +Every Turbo Native Module defines a `podspec` that looks like this: ### iOS @@ -109,7 +122,7 @@ To create a module that can work with both architectures, you need to configure Please note that this is currently the suggested approach. While it might lead to some code duplication, it will ensure the maximum compatibility with both architectures. You will see how to reduce the duplication in the next section. ::: -To configure the TurboModule so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: +To configure the Turbo Native Module so that it picks the proper sourceset, you have to update the `build.gradle` file in the following way: ```diff title="build.gradle" +// Add this function in case you don't have it already @@ -156,7 +169,7 @@ The file to change is the module implementation file, which is usually a `` type, generated by The New Architecture. -The **goal** is to make sure that the `TurboModule` still builds with the Old Architecture. To achieve that, we can wrap the `#import ".h"` and the `getTurboModule:` function into an `#ifdef RCT_NEW_ARCH_ENABLED` compilation directive, as shown in the following example: +The **goal** is to make sure that the `Turbo Native Module` still builds with the Old Architecture. To achieve that, we can wrap the `#import ".h"` and the `getTurboModule:` function into an `#ifdef RCT_NEW_ARCH_ENABLED` compilation directive, as shown in the following example: ```diff #import ".h" @@ -181,19 +194,19 @@ This snippet uses the same `RCT_NEW_ARCH_ENABLED` flag used in the previous [sec ### Android -As we can't use conditional compilation blocks on Android, we will define two different source sets. This will allow to create a backward compatible TurboModule with the proper source that is loaded and compiled depending on the used architecture. +As we can't use conditional compilation blocks on Android, we will define two different source sets. This will allow to create a backward compatible Turbo Native Module with the proper source that is loaded and compiled depending on the used architecture. Therefore, you have to: -1. Create a Native Module in the `src/oldarch` path. See [this guide](../native-modules-intro) to learn how to create a Native Module. -2. Create a TurboModule in the `src/newarch` path. See [this guide](./pillars-turbomodules) to learn how to create a TurboModule +1. Create a Legacy Native Module in the `src/oldarch` path. See [this guide](../native-modules-intro) to learn how to create a Legacy Native Module. +2. Create a Turbo Native Module in the `src/newarch` path. See [this guide](./pillars-turbomodules) to learn how to create a Turbo Native Module and then instruct Gradle to decide which implementation to pick. -Some files can be shared between a Native Module and a TurboModule: these should be created or moved into a folder that is loaded by both the architectures. These files are: +Some files can be shared between a Legacy Native Module and a Turbo Native Module: these should be created or moved into a folder that is loaded by both the architectures. These files are: - the `Package.java` file used to load the module. -- a `Impl.java` file where we can put the code that both the Native Module and the TurboModule has to execute. +- a `Impl.java` file where we can put the code that both the Legacy Native Module and the Turbo Native Module has to execute. The final folder structure looks like this: @@ -222,7 +235,7 @@ my-module └── package.json ``` -The code that should go in the `MyModuleImpl.java` and that can be shared by the Native Module and the TurboModule is, for example: +The code that should go in the `MyModuleImpl.java`, and that can be shared by the Legacy Native Module and the Turbo Native Module is, for example: ```java title="example of MyModuleImple.java" package com.MyModule; @@ -243,13 +256,13 @@ public class MyModuleImpl { } ``` -Then, the Native Module and the TurboModule can be updated with the following steps: +Then, the Legacy Native Module and the Turbo Native Module can be updated with the following steps: 1. Create a private instance of the `MyModuleImpl` class. 2. Initialize the instance in the module constructor. 3. Use the private instance in the modules methods. -For example, for a Native Module: +For example, for a Legacy Native Module: ```java title="Native Module using the Impl module" public class MyModule extends ReactContextBaseJavaModule { @@ -277,7 +290,7 @@ public class MyModule extends ReactContextBaseJavaModule { } ``` -And, for a TurboModule: +And, for a Turbo Native Module: ```java title="TurboModule using the Impl module" public class MyModule extends MyModuleSpec { @@ -313,7 +326,7 @@ For a step-by-step example on how to achieve this, have a look at [this repo](ht The last step makes sure that the JavaScript behaves transparently to chosen architecture. -For a TurboModule, the source of truth is the `Native.js` (or `.ts`) spec file. The app accesses the spec file like this: +For a Turbo Native Module, the source of truth is the `Native.js` (or `.ts`) spec file. The app accesses the spec file like this: ```ts import MyModule from 'your-module/src/index'; @@ -366,5 +379,5 @@ Whether you are using Flow or TypeScript for your specs, we understand which arc The `global.__turboModuleProxy` API may change in the future for a function that encapsulate this check. ::: -- If that object is `null`, the app has not enabled the TurboModule feature. It's running on the Old Architecture, and the fallback is to use the default [`NativeModule` implementation](../native-modules-intro). -- If that object is set, the app is running with the TurboModules enabled and it should use the `Native` spec to access the TurboModule. +- If that object is `null`, the app has not enabled the Turbo Native Module feature. It's running on the Old Architecture, and the fallback is to use the default [`Legacy Native Module` implementation](../native-modules-intro). +- If that object is set, the app is running with the Turbo Native Modules enabled, and it should use the `Native` spec to access the Turbo Native Module. diff --git a/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility.md b/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility.md index 89c1f3ac73f..babe5507485 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/backward-compatibility.md @@ -11,7 +11,7 @@ Creating a backward compatible module is important to provide a library that wor The trick to create a good backward compatible module is to minimize the changes required to adopt the new version. In that way, users of the module can smoothly move to the new version and migrate to the New Architecture when they are ready, ideally by issueing one different command. -To achieve this result, we have to perform few changes in our **TurboModule** and **Fabric Component** configurations. The steps we have to follow are: +To achieve this result, we have to perform few changes in our **Turbo Native Module** and **Fabric Native Component** configurations. The steps we have to follow are: 1. **Update the installation configuration** to avoid using code that is not needed by the Old Architecture. 1. **Update the code** to support both architectures. Both Android and iOS build pipelines gives you mechanism to provide a library that will compile with the correct React Native Architecture. @@ -21,5 +21,5 @@ To achieve this result, we have to perform few changes in our **TurboModule** an The next sections requires that you are familiar with the [Pillars](pillars) of the **New Architecture**. ::: -- To create a backward compatible **TurboModule**, follow [this guide](backward-compatibility-turbomodules). -- To create a backward compatible **Fabric Component**, follow [this guide](backward-compatibility-fabric-components). +- To create a backward compatible **Turbo Native Module**, follow [this guide](backward-compatibility-turbomodules). +- To create a backward compatible **Fabric Native Component**, follow [this guide](backward-compatibility-fabric-components). diff --git a/website/versioned_docs/version-0.70/the-new-architecture/landing-page.md b/website/versioned_docs/version-0.70/the-new-architecture/landing-page.md index 403a1dee659..c7bebdfcafc 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/landing-page.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/landing-page.md @@ -11,9 +11,9 @@ Starting from version 0.68, React Native provides the New Architecture, which of In order to achieve these benefits, we had to rethink how Native Modules and Native Components work. This led us to develop the [Pillars of the New Architecture](pillars): -- [TurboModules](pillars-turbomodules), a framework to support efficient and flexible integration with native code -- [Fabric renderer and components](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering -- [Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture, via static typing in JavaScript +- [The New Native Module System - Turbo Modules](pillars-turbomodules), a framework to support efficient and flexible integration with native code +- [The New Native Renderer - Fabric](pillars-fabric-components), which offer improved capabilities, cross-platform consistency, and performance in rendering +- [The Codegen](pillars-codegen), which generates boilerplate C++ required by the New Architecture via static typing in JavaScript ## Get started with the New Architecture diff --git a/website/versioned_docs/version-0.70/the-new-architecture/pillars-codegen.md b/website/versioned_docs/version-0.70/the-new-architecture/pillars-codegen.md index 11bd5062190..03262058d95 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/pillars-codegen.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/pillars-codegen.md @@ -11,7 +11,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import con The **Codegen** is not a proper pillar, but it is a tool that can be used to avoid writing of a lot of repetitive code. Using the **Codegen** is not mandatory: all the code that is generated by it can also be written manually. However, it generates scaffolding code that could save you a lot of time. -The **Codegen** is invoked automatically by React Native every time an iOS or an Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**TurboModules**](./pillars-turbomodules) and [**Fabric Components**](./pillars-fabric-components), for example. +The **Codegen** is invoked automatically by React Native every time an iOS or Android app is built. Occasionally, you would like to run the scripts that generate the code manually to know which types and files are actually generated: this is a common scenario when developing [**Turbo Native Modules**](./pillars-turbomodules) and [**Fabric Native Components**](./pillars-fabric-components), for example. This guide teaches how to configure the **Codegen**, how to invoke it manually for each platform, and it describes the generated code. @@ -35,12 +35,12 @@ Previous versions of React Native uses a version of **Codegen** that requires a Then, add the module that requires the **Codegen** as an NPM dependency of the app: ```sh -yarn add +yarn add ``` -See how to create a [TurboModule](pillars-turbomodules) or a [Fabric Component](pillars-fabric-components) to get more information on how to configure them. +See how to create a [Turbo Native Module](pillars-turbomodules) or a [Fabric Native Component](pillars-fabric-components) to get more information on how to configure them. -The rest of this guide assumes that you have a `TurboModule` and/or a `Fabric Component` properly set up. +The rest of this guide assumes that you have a `Turbo Native Module` and/or a `Fabric Native Component` properly set up. # iOS @@ -58,7 +58,7 @@ node node_modules/react_native/scripts/generate-artifacts.js \ --outputPath \ ``` -Given that the app has `TurboModules` and/or `Fabric Components` configured as a dependency, the **Codegen** will look for all of them and it will generate the code in the path you provided. +Given that the app has `Turbo Native Modules` and/or `Fabric Native Components` configured as a dependency, **Codegen** looks for all of them and generates the code in the path you provided. ## The Generated Code @@ -106,29 +106,29 @@ Then, there is an `ios` folder which contains: - A custom folder for each TurboModule. - The header (`.h`) and implementation (`.mm`) files for the `RCTThirdPartyFabricComponentsProvider`. -- A base `react/renderer/components` folder which contains a custom folder for each `Fabric Component`. +- A base `react/renderer/components` folder which contains a custom folder for each `Fabric Native Component`. -In the example above, there are both a TurboModule and a set of Fabric Components. These are generated by React Native itself: `FBReactNativeSpec` and `rncore`. These modules will always appear even if you don't have any extra TurboModule or Fabric Component: React Native requires them in order to work properly. +In the example above, there are both a TurboModule and a set of Fabric Native Components. These are generated by React Native itself: `FBReactNativeSpec` and `rncore`. These modules will always appear even if you don't have any extra TurboModule or Fabric Native Component: React Native requires them in order to work properly. -### TurboModules +### Turbo Native Modules -Each TurboModule's folder contains two files: an interface file and an implementation file. +Each folder contains two files: an interface file and an implementation file. -The interface files have the same name of the TurboModule and they contain methods to initialize the JSI interface. +The interface files have the same name as that of the Turbo Native Module and contain methods to initialize the JSI interface. The implementation files, instead, have the `-generated` suffix and they contains the logic to invoke the native methods from JS and viceversa. -### Fabric Components +### Fabric Native Components -The content of each Fabric Component folder contains several files. The basic element for a Fabric Componenent is the `ShadowNode`: it represents a node in the React absract tree. The `ShadowNode` represents a React entity, therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. +The content of each Fabric Native Component folder contains several files. The basic element for a Fabric Native Component is the `ShadowNode`: it represents a node in the React abstract tree. The `ShadowNode` represents a React entity; therefore, it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. -Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. +Additionally, the **Codegen** also creates a `ComponentDescriptor.h` and an `RCTComponentViewHelpers.h` files: the first one is used by React Native and Fabric to properly get a reference to the Native Component, while the latter contains some helper methods and protocols that can be implemented by the Native View to properly respond to JSI invocations. For further details about how Fabric works, have a look at the [Renderer](/architecture/fabric-renderer) section. ### RCTThirdPartyFabricComponentsProvider -These are an interface and an implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Component. Once React Native has an handle to that class, it can instantiate it. +These are an interface and an implementation files for a registry. React Native uses this registry at runtime to retrieve the right class for a required Fabric Native Component. Once React Native has an handle to that class, it can instantiate it. # Android @@ -145,11 +145,11 @@ After that, you can navigate into the `SampleApp/android` folder and run: ./gradlew generateCodegenArtifactsFromSchema ``` -This tasks invokes the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. +This tasks invokes the `generateCodegenArtifactsFromSchema` on all the the imported projects of the app (the app and all the node modules which are linked to it). It generates the code in the corresponding `node_modules/` folder. So, for example, if you have a Fabric Native Component whose node module is called `my-fabric-component`, the generated code is located in the `SampleApp/node_modules/my-fabric-component/android/build/generated/source/codegen` path. ## The Generated Code -Once the Gradle task completes, you can see different structures for a TurboModule or for a Fabric Component. The following tab shows how they appear: +Once the Gradle task completes, you can see different structures for a Turbo Native Module or for a Fabric Native Component. The following tab shows how they appear: @@ -215,18 +215,18 @@ codegen Java can't interoperate seamlessly with C++ as Objective-C++ does. To work properly, the **Codegen** creates some bridging between the Java and the C++ world in the `jni` folder, where the Java Native Interfaces are defined. -Notice that both TurboModules and Fabric Components comes with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. +Notice that both Turbo Native Modules and Fabric Native Components comes with two build file descriptors: the `Android.mk` and the `CMakeLists.txt`. These are used by the Android app to actually build the external modules. -### TurboModule +### Turbo Native Module The **Codegen** generates a Java abstract class in the `java` package with the same name of the TurboModule. This abstract class has to be implemented by the JNI C++ implementation. Then, it generates the C++ files in the `jni` folder. They follow the same iOS convention: there is an interface called `MyTurbomodule.h` and an implementation file called `MyTurbomodule-generated.cpp`. The former is an interface that allows React Natvie to initialize the JSI interface for the TurboModule. The latter is the implementation file which contains the logic to invoke the native method from JS and viceversa. -### Fabric Component +### Fabric Native Component -The **Codegen** for a Fabric Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Component](./pillars-fabric-components) for details). +The **Codegen** for a Fabric Native Component contains a `MyFabricComponentManagerInterface.java` and a `MyFabricComponentManagerDelegate.java` in the `java` package. They are implemented and used by the native `MyFabricComponentManager` required to properly load the component at runtime (See the guide on how to create a [Fabric Native Component](./pillars-fabric-components) for details). Then, there is a layer of JNI C++ files that are used by Fabric to render the components. The basic element for a Fabric Componenent is the `ShadowNode`: it represents a node in the React absract tree. The `ShadowNode` represents a React entity, therefore it could need some props, which are defined in the `Props` files and, sometimes, an `EventEmitter`, defined in the corresponding file. -The **Codegen** also creates a `ComponentDescriptor.h` which is required to get a proper handle to the Fabric Component. +The **Codegen** also creates a `ComponentDescriptor.h` which is required to get a proper handle to the Fabric Native Component. diff --git a/website/versioned_docs/version-0.70/the-new-architecture/pillars-fabric-components.md b/website/versioned_docs/version-0.70/the-new-architecture/pillars-fabric-components.md index a4271e49985..c5c174c1d24 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/pillars-fabric-components.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/pillars-fabric-components.md @@ -1,6 +1,6 @@ --- id: pillars-fabric-components -title: Fabric Components +title: Fabric Native Components --- import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; @@ -119,7 +119,7 @@ Finally, the spec file exports the returned value of the `codegenNativeComponent :::caution The JavaScript files imports types from libraries, without setting up a proper node module and installing its dependencies. The outcome of this is that the IDE may have troubles resolving the import statements and it can output errors and warnings. -These will disappear as soon as the Fabric Component is added as a dependency of a React Native app. +These will disappear as soon as the Fabric Native Component is added as a dependency of a React Native app. ::: ## 3. Component Configuration @@ -136,7 +136,7 @@ The shared configuration is a `package.json` file that will be used by yarn when { "name": "rtn-centered-text", "version": "0.0.1", - "description": "Showcase a Fabric Component with a centered text", + "description": "Showcase a Fabric Native Component with a centered text", "react-native": "js/index", "source": "js/index", "files": [ @@ -178,7 +178,7 @@ Then there are the dependencies for this package. For this guide, you need `reac Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a Fabric Component, thus the value to use is `components`. +- `type`: The type of module contained by this package. In this case, it is a Fabric Native Component, thus the value to use is `components`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. ### iOS: Create the `.podspec` file @@ -576,7 +576,7 @@ The `updateProps` method is invoked by Fabric every time a prop changes in JavaS Finally, the `RTNCenteredTextCls` is another static method used to retrieve the correct instance of the class at runtime. :::caution -Differently from Native Components, Fabric requires to manually implement the `updateProps` method. It's not enough to export properties with the `RCT_EXPORT_XXX` and `RCT_REMAP_XXX` macros. +Differently from Legacy Native Components, Fabric requires to manually implement the `updateProps` method. It's not enough to export properties with the `RCT_EXPORT_XXX` and `RCT_REMAP_XXX` macros. ::: ### Android @@ -630,13 +630,13 @@ codegen └── schema.json ``` -You can see that the content of the `codegen/jni/react/renderer/components/RTNCenteredTextSpecs` looks similar to the files created by the iOS counterpart. The `Android.mk` and `CMakeList.txt` files configure the Fabric Component in the app, while the `RTNCenteredTextManagerDelegate.java` and `RTNCenteredTextManagerInterface.java` files are meant use in your manager. +You can see that the content of the `codegen/jni/react/renderer/components/RTNCenteredTextSpecs` looks similar to the files created by the iOS counterpart. The `Android.mk` and `CMakeList.txt` files configure the Fabric Native Component in the app, while the `RTNCenteredTextManagerDelegate.java` and `RTNCenteredTextManagerInterface.java` files are meant use in your manager. See the [Codegen](./pillars-codegen) section for further details on the generated files. #### Write the Native Android Code -The native code for the Android side of a Fabric Components requires three pieces: +The native code for the Android side of a Fabric Native Components requires three pieces: 1. A `RTNCenteredText.java` that represents the actual view. 2. A `RTNCenteredTextManager.java` to instantiate the view. @@ -788,11 +788,11 @@ public class RTNCenteredTextPackage implements ReactPackage { } ``` -The added lines instantiate a new `RTNCenteredTextManager` object so that the React Native runtime can use it to render our Fabric Component. +The added lines instantiate a new `RTNCenteredTextManager` object so that the React Native runtime can use it to render our Fabric Native Component. -## 5. Adding the Fabric Component To Your App +## 5. Adding the Fabric Native Component To Your App -This is the last step to finally see your Fabric Component running on your app. +This is the last step to finally see your Fabric Native Component running on your app. ### Shared diff --git a/website/versioned_docs/version-0.70/the-new-architecture/pillars-turbomodule.md b/website/versioned_docs/version-0.70/the-new-architecture/pillars-turbomodule.md index 77159a4fc24..3be233a4736 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/pillars-turbomodule.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/pillars-turbomodule.md @@ -1,6 +1,6 @@ --- id: pillars-turbomodules -title: TurboModules +title: Turbo Native Modules --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; @@ -10,23 +10,23 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; If you've worked with React Native, you may be familiar with the concept of [Native Modules](../native-modules-intro.md), which allow JavaScript and platform-native code to communicate over the React Native "bridge", which handles cross-platform serialization via JSON. -TurboModules are the next iteration on Native Modules that provide a few extra [benefits](./why): +Turbo Native Modules are the next iteration on Native Modules that provide a few extra [benefits](./why): - Strongly typed interfaces that are consistent across platforms - The ability to write your code in C++, either exclusively or integrated with another native platform language, reducing the need to duplicate implementations across platforms - Lazy loading of modules, allowing for faster app startup - The use of JSI, a JavaScript interface for native code, which allows for more efficient communication between native and JavaScript code than the bridge -This guide will show you how to create a basic TurboModule. +This guide will show you how to create a basic Turbo Native Module compatible with React Native 0.70.0. :::caution -TurboModules only work with the **New Architecture** enabled. +Turbo Native Modules only work with the **New Architecture** enabled. To migrate to the **New Architecture**, follow the [Migration guide](../new-architecture-intro) ::: -## How to Create a TurboModule +## How to Create a Turbo Native Module -To create a TurboModule, we need to: +To create a Turbo Native Module, we need to: 1. Define the JavaScript specification. 2. Configure the module so that Codegen can generate the scaffolding. @@ -34,7 +34,7 @@ To create a TurboModule, we need to: ## 1. Folder Setup -In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app, and then add it as a dependency to your app later. This is also what you'll do for writing TurboModules that can be released as open-source libraries later. +In order to keep the module decoupled from the app, it's a good idea to define the module separately from the app and then add it as a dependency to your app later. This is also what you'll do for writing Turbo Native Modules that can be released as open-source libraries later. Next to your application, create a folder called `RTNCalculator`. **RTN** stands for "**R**eac**t** **N**ative", and is a recommended prefix for React Native modules. @@ -97,12 +97,12 @@ export default TurboModuleRegistry.get( At the beginning of the spec files are the imports: -- The `TurboModule` type, which defines the base interface for all TurboModules -- The `TurboModuleRegistry` JavaScript module, which contains functions for loading TurboModules +- The `TurboModule` type, which defines the base interface for all Turbo Native Modules +- The `TurboModuleRegistry` JavaScript module, which contains functions for loading Turbo Native Modules -The second section of the file contains the interface specification for the TurboModule. In this case, the interface defines the `add` function which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a TurboModule. +The second section of the file contains the interface specification for the Turbo Native Module. In this case, the interface defines the `add` function, which takes two numbers and returns a promise that resolves to a number. This interface type **must** be named `Spec` for a Turbo Native Module. -Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the TurboModule if it's available. +Finally, we invoke `TurboModuleRegistry.get`, passing the module's name, which will load the Turbo Native Module if it's available. :::caution We are writing JavaScript files importing types from libraries, without setting up a proper node module and installing its dependencies. Your IDE will not be able to resolve the import statements and you may see errors and warnings. This is expected and will not cause problems when you add the module to your app. @@ -122,7 +122,7 @@ The shared configuration is a `package.json` file that will be used by yarn when { "name": "rtn-calculator", "version": "0.0.1", - "description": "Add numbers with TurboModules", + "description": "Add numbers with Turbo Native Modules", "react-native": "js/index", "source": "js/index", "files": [ @@ -167,7 +167,7 @@ Then there are the dependencies for this package. For this guide, you need `reac Finally, the **Codegen** configuration is specified by the `codegenConfig` field. It contains an array of libraries, each of which is defined by three other fields: - `name`: The name of the library. By convention, you should add the `Spec` suffix. -- `type`: The type of module contained by this package. In this case, it is a TurboModule, thus the value to use is `modules`. +- `type`: The type of module contained by this package. In this case, it is a Turbo Native Module; thus, the value to use is `modules`. - `jsSrcsDir`: the relative path to access the `js` specification that is parsed by **Codegen**. - `android.javaPackageName`: the package to use in the Java files generated by **Codegen**. @@ -329,12 +329,12 @@ The `ReactPackage` interface is used by React Native to understand what native c ## 4. Native Code -For the final step in getting your TurboModule ready to go, you'll need to write some native code to connect the JavaScript side to the native platforms. This process requires two main steps: +For the final step in getting your Turbo Native Module ready to go, you'll need to write some native code to connect the JavaScript side to the native platforms. This process requires two main steps: - Run **Codegen** to see what it generates. - Write your native code, implementing the generated interfaces. -When developing a React Native app that uses a TurboModule, it is responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore useful to see what the app will generate. +When developing a React Native app that uses a Turbo Native Module, it is the responsibility of the app to actually generate the code using **Codegen**. However, when developing a TurboModule as a library, we need to reference the generated code, and it is therefore, useful to see what the app will generate. As first step for both iOS and Android, this guide shows how to execute manually the scripts used by **Codegen** to generate the required code. Further information on **Codegen** can be found [here](pillars-codegen.md) @@ -390,7 +390,7 @@ generated └── ShadowNodes.h ``` -The relevant path for the TurboModule interface is `generated/build/generated/ios/RTNCalculatorSpec`. +The relevant path for the Turbo Native Module interface is `generated/build/generated/ios/RTNCalculatorSpec`. See the [Codegen](./pillars-codegen) section for further details on the generated files. @@ -407,7 +407,7 @@ rm -rf build #### Write the Native iOS Code -Now add the Native code for your TurboModule. Create two files in the `RTNCalculator/ios` folder: +Now add the Native code for your Turbo Native Module. Create two files in the `RTNCalculator/ios` folder: 1. The `RTNCalculator.h`, a header file for the module. 2. The `RTNCalculator.mm`, the implementation of the module. @@ -456,11 +456,11 @@ RCT_REMAP_METHOD(add, addA:(NSInteger)a @end ``` -The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that React Native can load the TurboModule. +The most important call is to the `RCT_EXPORT_MODULE`, which is required to export the module so that React Native can load the Turbo Native Module. Then the `RCT_REMAP_METHOD` macro is used to expose the `add` method. -Finally, the `getTurboModule` method gets an instance of the TurboModule so that the JavaScript side can invoke its methods. The function is defined in (and requested by) the `RTNCalculatorSpec.h` file that was generated earlier by Codegen. +Finally, the `getTurboModule` method gets an instance of the Turbo Native Module so that the JavaScript side can invoke its methods. The function is defined in (and requested by) the `RTNCalculatorSpec.h` file that was generated earlier by Codegen. :::info There are other macros that can be used to export modules and methods. You view the code that specifies them [here](https://github.com/facebook/react-native/blob/main/React/Base/RCTBridgeModule.h). @@ -516,7 +516,7 @@ codegen #### Write the Native Android Code -The native code for the Android side of a TurboModule requires: +The native code for the Android side of a Turbo Native Module requires: 1. to create a `RTNCalculatorModule.java` that implements the module. 2. to update the `RTNCalculatorPackage.java` created in the previous step. @@ -628,9 +628,9 @@ public class CalculatorPackage extends TurboReactPackage { This is the last piece of Native Code for Android. It defines the `TurboReactPackage` object that will be used by the app to load the module. -## 5. Adding the TurboModule to your App +## 5. Adding the Turbo Native Module to your App -Now you can install and use the TurboModule in your app. +Now you can install and use the Turbo Native Module in your app. ### Shared @@ -667,7 +667,7 @@ Android configuration requires to enable the **New Architecture**: ### JavaScript -Now you can use your TurboModule calculator in your app! +Now you can use your Turbo Native Module calculator in your app! Here's an example App.js file using the `add` method: @@ -711,4 +711,4 @@ const App: () => Node = () => { export default App; ``` -Try this out to see your TurboModule in action! +Try this out to see your Turbo Native Module in action! diff --git a/website/versioned_docs/version-0.70/the-new-architecture/pillars.md b/website/versioned_docs/version-0.70/the-new-architecture/pillars.md index 8a0841c1eff..24db249ce43 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/pillars.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/pillars.md @@ -7,14 +7,23 @@ import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; -The New Architecture is composed mainly by two pillars: +The New Architecture is composed mainly of two pillars: -- [TurboModules](pillars-turbomodules) -- [Fabric Components](pillars-fabric-components). +- [The New Native Module System - Turbo Modules](pillars-turbomodules) +- [The New Renderer - Fabric](pillars-fabric-components). + +The core concepts of React Native still holds true in the New Architecture: Native Modules are the preferred way to create libraries that leverage some platform-specific API. Native Components are the preferred way to create reusable UI components, providing a native experience to the users. TurboModules are the preferred way to create libraries that leverage some platform specific API. Fabric Components are the preferred way to create reusable UI components, providing a native experience to the users. -The main goal of this section is to drive the reader through a step-by-step guide to create their first TurboModule or Fabric Component. +The main goal of this section is to drive the reader through a step-by-step guide to create their first Native Module or Component which is compatible with the New Architecture. + +:::info +For the sake of this guide we're going to use the following **terminology**: + +- **Legacy Native Components** & **Legacy Native Modules** - To refer to Modules and Components which are running on the old React Native architecture. +- **Fabric Native Components** & **Turbo Native Modules** - To refer to Modules and Components which have been adapted to work well with the New Architecture, namely the new renderer and the new Native Module System. For brevity you might find them referred as **Fabric Components** and **Turbo Modules** + ::: The next sections contain an high-level overview of the pillars, together with the steps to create them. To create one of these pillars, the steps are: @@ -26,7 +35,7 @@ The next sections contain an high-level overview of the pillars, together with t Finally, we dive a little deeper into the [Codegen](pillars-codegen) process that is required to create all the C++ types and files used by our components, including some useful steps to work comfortably while developing the component. :::caution -To integrate a TurboModule or a Fabric Component in an app, the app has to run with the New Architecture enabled. +The app has to run with the **New Architecture enabled to integrate a Turbo Native Module or a Fabric Native Component** in an app. To create a new app adopting the New Architecture, refer to the [Using the App Template](use-app-template) section. To migrate an existing app to the New Architecture, refer to the [Migration](../new-architecture-intro) guide. diff --git a/website/versioned_docs/version-0.70/the-new-architecture/use-app-template.md b/website/versioned_docs/version-0.70/the-new-architecture/use-app-template.md index ca4ed3d3dad..04fcd9b3091 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/use-app-template.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/use-app-template.md @@ -123,10 +123,10 @@ For further explanations of what each file is doing, check out these guides to w #### Android -- [Enabling TurboModules on Android](new-architecture-app-modules-android.md) -- [Enabling Fabric on Android](new-architecture-app-renderer-android.md) +- [Enabling the New Native Module System (Turbo Module) on Android](new-architecture-app-modules-android.md) +- [Enabling the New Renderer (Fabric) on Android](new-architecture-app-renderer-android.md) #### iOS -- [Enabling TurboModules on iOS](new-architecture-app-modules-ios.md) -- [Enabling Fabric on iOS](new-architecture-app-renderer-ios.md) +- [Enabling the New Native Module System (Turbo Module) on iOS](new-architecture-app-modules-ios.md) +- [Enabling the New Renderer (Fabric) on iOS](new-architecture-app-renderer-ios.md) diff --git a/website/versioned_docs/version-0.70/the-new-architecture/why.md b/website/versioned_docs/version-0.70/the-new-architecture/why.md index 47bb4e7dd8e..fb5723d0eb3 100644 --- a/website/versioned_docs/version-0.70/the-new-architecture/why.md +++ b/website/versioned_docs/version-0.70/the-new-architecture/why.md @@ -35,7 +35,7 @@ This idea allowed to unlock several benefits: - **Code sharing:** by introducing C++, it is now possible to abstract all the platform agnostic code and to share it with ease between the plaforms. - **Type safety:** to make sure that JS can properly invoke methods on C++ objects and viceversa, a layer of code automatically generated has been added. The code is generated starting from some JS specification that must be typed through Flow or TypeScript. -These advantages are the foundations of the [TurboModule](pillars-turbomodules) system and a jumping stone to further enhancements. For example, it has been possible to develop a new renderer which is faster and more performant: [Fabric](/architecture/fabric-renderer) and its [Fabric Components](pillars-fabric-components). +These advantages are the foundations of the [New Native Module System](pillars-turbomodules) and a jumping stone to further enhancements. For example, it has been possible to develop a [new renderer](/architecture/fabric-renderer) which offers faster and more performant [Native Components](pillars-fabric-components). ## Further Reading From 38cd75a4064debf2da7186d3e328928f83bbe63b Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Tue, 13 Sep 2022 19:24:25 +0100 Subject: [PATCH 21/88] Remove unnecessary box from Legacy Native Modules/Components (#3313) --- docs/native-modules-android.md | 2 -- docs/native-modules-ios.md | 2 -- website/versioned_docs/version-0.70/native-modules-android.md | 2 -- website/versioned_docs/version-0.70/native-modules-ios.md | 2 -- 4 files changed, 8 deletions(-) diff --git a/docs/native-modules-android.md b/docs/native-modules-android.md index df5066d7e2c..3596e0038f9 100644 --- a/docs/native-modules-android.md +++ b/docs/native-modules-android.md @@ -14,8 +14,6 @@ Welcome to Native Modules for Android. Please start by reading the [Native Modul In the following guide you will create a native module, `CalendarModule`, that will allow you to access Android’s calendar APIs from JavaScript. By the end, you will be able to call `CalendarModule.createCalendarEvent('Dinner Party', 'My House');` from JavaScript, invoking a Java/Kotlin method that creates a calendar event. -> The React Native team is currently working on a re-architecture of the Native Module system. This new system is called TurboModules, and it will help facilitate more efficient type-safe communication between JavaScript and native, without relying on the React Native bridge. It will also enable new extensions that weren't possible with the legacy Native Module system. You can read more about it [here](https://github.com/react-native-community/discussions-and-proposals/issues/40). Throughout these docs we have added notes around parts of Native Modules that will change in the TurboModules release and how you can best prepare for a smooth upgrade to TurboModules. - ### Setup To get started, open up the Android project within your React Native application in Android Studio. You can find your Android project here within a React Native app: diff --git a/docs/native-modules-ios.md b/docs/native-modules-ios.md index 433acc37cd0..ae590ad6cd2 100644 --- a/docs/native-modules-ios.md +++ b/docs/native-modules-ios.md @@ -13,8 +13,6 @@ Welcome to Native Modules for iOS. Please start by reading the [Native Modules I In the following guide you will create a native module, `CalendarModule`, that will allow you to access Apple's calendar APIs from JavaScript. By the end you will be able to call `CalendarModule.createCalendarEvent('Dinner Party', 'My House');` from JavaScript, invoking a native method that creates a calendar event. -> The React Native team is currently working on a re-architecture of the Native Module system. This new system is called TurboModules, and it will help facilitate more efficient type-safe communication between JavaScript and native, without relying on the React Native bridge. It will also enable new extensions that weren't possible with the legacy Native Module system. You can read more about it [here](https://github.com/react-native-community/discussions-and-proposals/issues/40). Throughout these docs we have added notes around parts of Native Modules that will change in the TurboModules release and how you can best prepare for a smooth upgrade to TurboModules. - ### Setup To get started, open up the iOS project within your React Native application in Xcode. You can find your iOS project here within a React Native app: diff --git a/website/versioned_docs/version-0.70/native-modules-android.md b/website/versioned_docs/version-0.70/native-modules-android.md index df5066d7e2c..3596e0038f9 100644 --- a/website/versioned_docs/version-0.70/native-modules-android.md +++ b/website/versioned_docs/version-0.70/native-modules-android.md @@ -14,8 +14,6 @@ Welcome to Native Modules for Android. Please start by reading the [Native Modul In the following guide you will create a native module, `CalendarModule`, that will allow you to access Android’s calendar APIs from JavaScript. By the end, you will be able to call `CalendarModule.createCalendarEvent('Dinner Party', 'My House');` from JavaScript, invoking a Java/Kotlin method that creates a calendar event. -> The React Native team is currently working on a re-architecture of the Native Module system. This new system is called TurboModules, and it will help facilitate more efficient type-safe communication between JavaScript and native, without relying on the React Native bridge. It will also enable new extensions that weren't possible with the legacy Native Module system. You can read more about it [here](https://github.com/react-native-community/discussions-and-proposals/issues/40). Throughout these docs we have added notes around parts of Native Modules that will change in the TurboModules release and how you can best prepare for a smooth upgrade to TurboModules. - ### Setup To get started, open up the Android project within your React Native application in Android Studio. You can find your Android project here within a React Native app: diff --git a/website/versioned_docs/version-0.70/native-modules-ios.md b/website/versioned_docs/version-0.70/native-modules-ios.md index 433acc37cd0..ae590ad6cd2 100644 --- a/website/versioned_docs/version-0.70/native-modules-ios.md +++ b/website/versioned_docs/version-0.70/native-modules-ios.md @@ -13,8 +13,6 @@ Welcome to Native Modules for iOS. Please start by reading the [Native Modules I In the following guide you will create a native module, `CalendarModule`, that will allow you to access Apple's calendar APIs from JavaScript. By the end you will be able to call `CalendarModule.createCalendarEvent('Dinner Party', 'My House');` from JavaScript, invoking a native method that creates a calendar event. -> The React Native team is currently working on a re-architecture of the Native Module system. This new system is called TurboModules, and it will help facilitate more efficient type-safe communication between JavaScript and native, without relying on the React Native bridge. It will also enable new extensions that weren't possible with the legacy Native Module system. You can read more about it [here](https://github.com/react-native-community/discussions-and-proposals/issues/40). Throughout these docs we have added notes around parts of Native Modules that will change in the TurboModules release and how you can best prepare for a smooth upgrade to TurboModules. - ### Setup To get started, open up the iOS project within your React Native application in Xcode. You can find your iOS project here within a React Native app: From 046801154da4c379605d1966c704371373eee7fb Mon Sep 17 00:00:00 2001 From: JiashengWu Date: Wed, 14 Sep 2022 00:19:07 -0700 Subject: [PATCH 22/88] Fix title case in testing-overview.md (#3322) --- docs/testing-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/testing-overview.md b/docs/testing-overview.md index 4216c7ff9cd..be92a4f626c 100644 --- a/docs/testing-overview.md +++ b/docs/testing-overview.md @@ -73,7 +73,7 @@ If your test has many steps or many expectations, you probably want to split it Lastly, as developers we like when our code works great and doesn't crash. With tests, this is often the opposite. Think of a failed test as of a _good thing!_ When a test fails, it often means something is not right. This gives you an opportunity to fix the problem before it impacts the users. -## Unit tests +## Unit Tests Unit tests cover the smallest parts of code, like individual functions or classes. From 791d9d12898851b7e4030ba80f2b28995067332c Mon Sep 17 00:00:00 2001 From: Riccardo Date: Wed, 14 Sep 2022 10:39:08 +0200 Subject: [PATCH 23/88] [FEAT] Add doc to simplify podspecs for Native Modules and Native Components (#3321) * [FEAT] Add doc to simplify podspecs for Native Modules and Native Components * fix: apply suggested changes I Co-authored-by: Arati Chilad <58401542+arati-1@users.noreply.github.com> * fix: apply suggested changes II Co-authored-by: Arati Chilad <58401542+arati-1@users.noreply.github.com> * fix: apply suggested changes III Co-authored-by: Arati Chilad <58401542+arati-1@users.noreply.github.com> * fix: apply suggested changes IV Co-authored-by: Arati Chilad <58401542+arati-1@users.noreply.github.com> * fix: apply suggested changes V Co-authored-by: Arati Chilad <58401542+arati-1@users.noreply.github.com> * fix: apply suggested changes VI Co-authored-by: Arati Chilad <58401542+arati-1@users.noreply.github.com> Co-authored-by: Arati Chilad <58401542+arati-1@users.noreply.github.com> --- docs/new-architecture-library-ios.md | 26 +++------ ...ackward-compatibility-fabric-components.md | 58 +++++++++++++------ .../backward-compatibility-turbomodules.md | 57 ++++++++++++------ .../pillars-fabric-components.md | 23 ++------ .../pillars-turbomodule.md | 22 ++----- 5 files changed, 92 insertions(+), 94 deletions(-) diff --git a/docs/new-architecture-library-ios.md b/docs/new-architecture-library-ios.md index 1fb8eee0851..15f8e70bb32 100644 --- a/docs/new-architecture-library-ios.md +++ b/docs/new-architecture-library-ios.md @@ -16,32 +16,20 @@ The New Architecture makes use of CocoaPods. ### Add Folly and Other Dependencies -We'll need to ensure Folly is configured properly in any projects that consume your library. With CocoaPods, we can use the `compiler_flags` and `dependency` properties to set it up. - -Add these to your `Pod::Spec.new` block: - -```ruby -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' +The New Architecture requires some specific dependencies to work properly. You can set up your podspec to automatically install the required dependencies by modifying the `.podspec` file. In your `Pod::Spec.new` block, add the following line: +```diff Pod::Spec.new do |s| # ... - s.compiler_flags = folly_compiler_flags - - s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"" - } - - s.dependency "React-Core" - s.dependency "React-RCTFabric" # This is for Fabric Native Component - s.dependency "React-Codegen" - s.dependency "RCT-Folly" - s.dependency "RCTRequired" - s.dependency "RCTTypeSafety" - s.dependency "ReactCommon/turbomodule/core" ++ install_modules_dependencies(s) # ... end ``` +At this [link](https://github.com/facebook/react-native/blob/82e9c6ad611f1fb816de056ff031716f8cb24b4e/scripts/react_native_pods.rb#L139-L144), you can find the documentation of the `install_modules_dependencies` function. + +If you need to explicitly know which `folly_flags` React Native is using, you can query them using the [`folly_flag`](https://github.com/facebook/react-native/blob/82e9c6ad611f1fb816de056ff031716f8cb24b4e/scripts/react_native_pods.rb#L135) function. + ## 2. Extend or Implement the Code-generated Native Interfaces The JavaScript spec for your native module or component will be used to generate native interface code for each supported platform (i.e., Android and iOS). These native interface files will be generated when a React Native application that depends on your library is built. diff --git a/docs/the-new-architecture/backward-compatibility-fabric-components.md b/docs/the-new-architecture/backward-compatibility-fabric-components.md index 8f67e7dcc1d..21e65220483 100644 --- a/docs/the-new-architecture/backward-compatibility-fabric-components.md +++ b/docs/the-new-architecture/backward-compatibility-fabric-components.md @@ -40,7 +40,9 @@ While the last step is the same for all the platforms, the first two steps are d The Apple platform installs Fabric Native Components using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every Fabric Native Component defines a `podspec` that looks like this: +If you are already using the [`install_module_dependencies`](https://github.com/facebook/react-native/blob/82e9c6ad611f1fb816de056ff031716f8cb24b4e/scripts/react_native_pods.rb#L145) function, then **there is nothing to do**. The function already takes care of installing the proper dependencies when the New Architecture is enabled and avoiding them when it is not enabled. + +Otherwise, your Fabric Native Component's `podspec` should look like this: ```ruby require "json" @@ -83,32 +85,50 @@ Pod::Spec.new do |s| end ``` -The **goal** is to avoid installing the dependencies when the app is prepared for the Old Architecture. +You should install the extra dependencies when the New Architecture is enabled, and avoid installing them when it's not. +To achieve this, you can use the [`install_modules_dependencies`](https://github.com/facebook/react-native/blob/82e9c6ad611f1fb816de056ff031716f8cb24b4e/scripts/react_native_pods.rb#L145). Update the `.podspec` file as it follows: -When we want to install the dependencies, we use the following commands depending on the architecture: +```diff +require "json" -```sh -# For the Old Architecture, we use: -pod install +package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -# For the New Architecture, we use: -RCT_NEW_ARCH_ENABLED=1 pod install -``` +- folly_version = '2021.07.22.00' +- folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -Therefore, we can leverage this environment variable in the `podspec` to exclude the settings and the dependencies that are related to the New Architecture: +Pod::Spec.new do |s| + # Default fields for a valid podspec + s.name = "" + s.version = package["version"] + s.summary = package["description"] + s.description = package["description"] + s.homepage = package["homepage"] + s.license = package["license"] + s.platforms = { :ios => "11.0" } + s.author = package["author"] + s.source = { :git => package["repository"], :tag => "#{s.version}" } -```diff -+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then - # The following lines are required by the New Architecture. - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" - # ... other dependencies ... - s.dependency "ReactCommon/turbomodule/core" -+ end + s.source_files = "ios/**/*.{h,m,mm,swift}" + # React Native Core dependency ++ install_modules_dependencies(s) +- s.dependency "React-Core" +- # The following lines are required by the New Architecture. +- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" +- s.pod_target_xcconfig = { +- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", +- "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", +- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" +- } +- +- s.dependency "React-RCTFabric" +- s.dependency "React-Codegen" +- s.dependency "RCT-Folly", folly_version +- s.dependency "RCTRequired" +- s.dependency "RCTTypeSafety" +- s.dependency "ReactCommon/turbomodule/core" end ``` -This `if` guard prevents the dependencies from being installed when the environment variable is not set. - ### Android To create a Native Component that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. diff --git a/docs/the-new-architecture/backward-compatibility-turbomodules.md b/docs/the-new-architecture/backward-compatibility-turbomodules.md index 590220e6453..2cdc68f1608 100644 --- a/docs/the-new-architecture/backward-compatibility-turbomodules.md +++ b/docs/the-new-architecture/backward-compatibility-turbomodules.md @@ -40,7 +40,9 @@ While the last step is the same for all the platforms, the first two steps are d The Apple platform installs Turbo Native Modules using [Cocoapods](https://cocoapods.org) as a dependency manager. -Every Turbo Native Module defines a `podspec` that looks like this: +If you are already using the [`install_module_dependencies`](https://github.com/facebook/react-native/blob/82e9c6ad611f1fb816de056ff031716f8cb24b4e/scripts/react_native_pods.rb#L145) function, then **there is nothing to do**. The function already takes care of installing the proper dependencies when the New Architecture is enabled and avoids them when it is not enabled. + +Otherwise, your Turbo Native Module's `podspec` should look like this: ```ruby require "json" @@ -82,32 +84,49 @@ Pod::Spec.new do |s| end ``` -The **goal** is to avoid installing the dependencies when the app is prepared for the Old Architecture. +You should install the extra dependencies when the New Architecture is enabled, and avoid installing them when it's not. +To achieve this, you can use the [`install_modules_dependencies`](https://github.com/facebook/react-native/blob/82e9c6ad611f1fb816de056ff031716f8cb24b4e/scripts/react_native_pods.rb#L145). Update the `.podspec` file as it follows: -When we want to install the dependencies we use the following commands, depending on the architecture: +```diff +require "json" -```sh -# For the Old Architecture, we use: -pod install +package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -# For the New Architecture, we use: -RCT_NEW_ARCH_ENABLED=1 pod install -``` +-folly_version = '2021.07.22.00' +-folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -Therefore, we can leverage this environment variable in the `podspec` to exclude the settings and the dependencies, that are related to the New Architecture: +Pod::Spec.new do |s| + # Default fields for a valid podspec + s.name = "" + s.version = package["version"] + s.summary = package["description"] + s.description = package["description"] + s.homepage = package["homepage"] + s.license = package["license"] + s.platforms = { :ios => "11.0" } + s.author = package["author"] + s.source = { :git => package["repository"], :tag => "#{s.version}" } -```diff -+ if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then - # The following lines are required by the New Architecture. - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" - # ... other dependencies ... - s.dependency "ReactCommon/turbomodule/core" -+ end + s.source_files = "ios/**/*.{h,m,mm,swift}" + # React Native Core dependency ++ install_modules_dependencies(s) +- s.dependency "React-Core" +- +- # The following lines are required by the New Architecture. +- s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" +- s.pod_target_xcconfig = { +- "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", +- "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" +- } +- +- s.dependency "React-Codegen" +- s.dependency "RCT-Folly", folly_version +- s.dependency "RCTRequired" +- s.dependency "RCTTypeSafety" +- s.dependency "ReactCommon/turbomodule/core" end ``` -This `if` guard prevents the dependencies from being installed when the environment variable is not set. - ### Android To create a module that can work with both architectures, you need to configure Gradle to choose which files need to be compiled depending on the chosen architecture. This can be achieved by using **different source sets** in the Gradle configuration. diff --git a/docs/the-new-architecture/pillars-fabric-components.md b/docs/the-new-architecture/pillars-fabric-components.md index 8b4af25fad4..e1268e213a2 100644 --- a/docs/the-new-architecture/pillars-fabric-components.md +++ b/docs/the-new-architecture/pillars-fabric-components.md @@ -192,9 +192,6 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_version = '2021.07.22.00' -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' - Pod::Spec.new do |s| s.name = "rtn-centered-text" s.version = package["version"] @@ -208,27 +205,15 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm,swift}" - s.dependency "React-Core" - - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" - s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", - "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" - } - - s.dependency "React-RCTFabric" - s.dependency "React-Codegen" - s.dependency "RCT-Folly", folly_version - s.dependency "RCTRequired" - s.dependency "RCTTypeSafety" - s.dependency "ReactCommon/turbomodule/core" + install_modules_dependencies(s) end ``` The `.podspec` file has to be a sibling of the `package.json` file, and its name is the one we set in the `package.json`'s `name` property: `rtn-centered-text`. -The first part of the file prepares some variables we will use throughout the rest of it. Then, there is a section that contains some information used to configure the pod, like its name, version, and description. Finally, we have a set of dependencies that the New Architecture requires. +The first part of the file prepares some variables that we use throughout the file. Then, there is a section that contains some information used to configure the pod, like its name, version, and description. + +All the requirements for the New Architecture have been encapsulated in the [`install_modules_dependencies`](https://github.com/facebook/react-native/blob/82e9c6ad611f1fb816de056ff031716f8cb24b4e/scripts/react_native_pods.rb#L145). It takes care of installing the proper dependencies based on which architecture is currently enabled. It also automatically installs the `React-Core` dependency in the old architecture. ### Android: `build.gradle`, `AndroidManifest.xml`, a `ReactPackage` class diff --git a/docs/the-new-architecture/pillars-turbomodule.md b/docs/the-new-architecture/pillars-turbomodule.md index 29f8c2a775a..40399127b7b 100644 --- a/docs/the-new-architecture/pillars-turbomodule.md +++ b/docs/the-new-architecture/pillars-turbomodule.md @@ -182,9 +182,6 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_version = '2021.07.22.00' -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' - Pod::Spec.new do |s| s.name = "rtn-calculator" s.version = package["version"] @@ -198,26 +195,15 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm,swift}" - s.dependency "React-Core" - - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" - s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", - "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" - } - - s.dependency "React-Codegen" - s.dependency "RCT-Folly", folly_version - s.dependency "RCTRequired" - s.dependency "RCTTypeSafety" - s.dependency "ReactCommon/turbomodule/core" + install_modules_dependencies(s) end ``` The `.podspec` file has to be a sibling of the `package.json` file, and its name is the one we set in the `package.json`'s `name` property: `rtn-calculator`. -The first part of the file prepares some variables we will use throughout the rest of it. Then, there is a section that contains some information used to configure the pod, like its name, version, and description. Finally, we have a set of dependencies that are required by the New Architecture. +The first part of the file prepares some variables that we use throughout the file. Then, there is a section that contains some information used to configure the pod, like its name, version, and description. + +All the requirements for the New Architecture have been encapsulated in the [`install_modules_dependencies`](https://github.com/facebook/react-native/blob/82e9c6ad611f1fb816de056ff031716f8cb24b4e/scripts/react_native_pods.rb#L145). It takes care of installing the proper dependencies based on which architecture is currently enabled. It also automatically installs the `React-Core` dependency in the old architecture. ### Android: `build.gradle`, `AndroidManifest.xml`, a `ReactPackage` class From 1285a79f393a83f208f9b47243c6ee01aa6cc5c3 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Thu, 15 Sep 2022 11:21:03 +0200 Subject: [PATCH 24/88] [Fix] Improve Getting started with iOS (#3323) --- docs/_getting-started-macos-ios.md | 44 +++++++++++++++---- .../_getting-started-macos-ios.md | 44 +++++++++++++++---- 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/docs/_getting-started-macos-ios.md b/docs/_getting-started-macos-ios.md index 9860a4cc4ba..2f5f3eb9699 100644 --- a/docs/_getting-started-macos-ios.md +++ b/docs/_getting-started-macos-ios.md @@ -2,7 +2,7 @@ import M1Cocoapods from './\_markdown-m1-cocoapods.mdx'; import RemoveGlobalCLI ## Installing dependencies -You will need Node, Watchman, the React Native command line interface, Xcode and CocoaPods. +You will need Node, Watchman, the React Native command line interface, a Ruby version manager, Xcode and CocoaPods. While you can use any editor of your choice to develop your app, you will need to install Xcode in order to set up the necessary tooling to build your React Native app for iOS. @@ -19,6 +19,31 @@ If you have already installed Node on your system, make sure it is Node 14 or ne [Watchman](https://facebook.github.io/watchman) is a tool by Facebook for watching changes in the filesystem. It is highly recommended you install it for better performance. +### Ruby + +React Native uses a `.ruby-version` file to make sure that your version of Ruby is aligned with what is needed. Currently, macOS 12.5.1 is shipped with Ruby 2.6.8, which is **not** what is required by React Native. Our suggestion is to install a Ruby version manager and to install the proper version of Ruby in your system. + +Some common Ruby version manager are: + +- [rbenv](https://github.com/rbenv/rbenv) +- [RVM](https://rvm.io/) +- [chruby](https://github.com/postmodern/chruby) +- [asdf-vm](https://github.com/asdf-vm) with the [asdf-ruby](https://github.com/asdf-vm/asdf-ruby) plugin + +To check what is your current version of Ruby, you can run this command: + +``` +ruby --version +``` + +React Native uses [this version](https://github.com/facebook/react-native/blob/main/template/_ruby-version) of Ruby. You can also find which version your specific project needs in the `.ruby-version` file at root of your RN project. + +### Bundler + +[Bundler](https://bundler.io/) is a Ruby gem that helps managing the Ruby dependencies of your project. We need Ruby to install Cocoapods and using Bundler will make sure that all the dependencies are aligned and that the project works properly. + +If you want to learn more about why we need this tool, you can read [this article](https://bundler.io/guides/rationale.html#bundlers-purpose-and-rationale). + ### Xcode The easiest way to install Xcode is via the [Mac App Store](https://itunes.apple.com/us/app/xcode/id497799835?mt=12). Installing Xcode will also install the iOS Simulator and all the necessary tools to build your iOS app. @@ -39,14 +64,6 @@ To install a simulator, open Xcode > Preferences... and select [CocoaPods](https://cocoapods.org/) is built with Ruby and it will be installable with the default Ruby available on macOS. -Using the default Ruby available on macOS will require you to use `sudo` when installing gems. (This is only an issue for the duration of the gem installation, though.) - -```shell -sudo gem install cocoapods -``` - -Otherwise you can use a Ruby version manager, such as `rbenv`. Apps created with the command `npx react-native init` described below are configured to work well with `rbenv` and will pick the correct Ruby version requested by the template. - For more information, please visit [CocoaPods Getting Started guide](https://guides.cocoapods.org/using/getting-started.html). @@ -67,6 +84,15 @@ npx react-native init AwesomeProject This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Expo, or if you're adding iOS support to an existing React Native project (see [Integration with Existing Apps](integration-with-existing-apps.md)). You can also use a third-party CLI to init your React Native app, such as [Ignite CLI](https://github.com/infinitered/ignite). +:::info +If you are having trouble with iOS, try to reinstall the dependencies by running: + +1. `cd ios` to navigate to the +2. `bundle install` to install Bundler + 1. If needed: install a [Ruby Version Manager](#ruby) and update the Ruby version +3. `bundle exec pod install` to install the iOS dependencies. + ::: + ### [Optional] Using a specific version or template If you want to start a new project with a specific React Native version, you can use the `--version` argument: diff --git a/website/versioned_docs/version-0.70/_getting-started-macos-ios.md b/website/versioned_docs/version-0.70/_getting-started-macos-ios.md index 9860a4cc4ba..2f5f3eb9699 100644 --- a/website/versioned_docs/version-0.70/_getting-started-macos-ios.md +++ b/website/versioned_docs/version-0.70/_getting-started-macos-ios.md @@ -2,7 +2,7 @@ import M1Cocoapods from './\_markdown-m1-cocoapods.mdx'; import RemoveGlobalCLI ## Installing dependencies -You will need Node, Watchman, the React Native command line interface, Xcode and CocoaPods. +You will need Node, Watchman, the React Native command line interface, a Ruby version manager, Xcode and CocoaPods. While you can use any editor of your choice to develop your app, you will need to install Xcode in order to set up the necessary tooling to build your React Native app for iOS. @@ -19,6 +19,31 @@ If you have already installed Node on your system, make sure it is Node 14 or ne [Watchman](https://facebook.github.io/watchman) is a tool by Facebook for watching changes in the filesystem. It is highly recommended you install it for better performance. +### Ruby + +React Native uses a `.ruby-version` file to make sure that your version of Ruby is aligned with what is needed. Currently, macOS 12.5.1 is shipped with Ruby 2.6.8, which is **not** what is required by React Native. Our suggestion is to install a Ruby version manager and to install the proper version of Ruby in your system. + +Some common Ruby version manager are: + +- [rbenv](https://github.com/rbenv/rbenv) +- [RVM](https://rvm.io/) +- [chruby](https://github.com/postmodern/chruby) +- [asdf-vm](https://github.com/asdf-vm) with the [asdf-ruby](https://github.com/asdf-vm/asdf-ruby) plugin + +To check what is your current version of Ruby, you can run this command: + +``` +ruby --version +``` + +React Native uses [this version](https://github.com/facebook/react-native/blob/main/template/_ruby-version) of Ruby. You can also find which version your specific project needs in the `.ruby-version` file at root of your RN project. + +### Bundler + +[Bundler](https://bundler.io/) is a Ruby gem that helps managing the Ruby dependencies of your project. We need Ruby to install Cocoapods and using Bundler will make sure that all the dependencies are aligned and that the project works properly. + +If you want to learn more about why we need this tool, you can read [this article](https://bundler.io/guides/rationale.html#bundlers-purpose-and-rationale). + ### Xcode The easiest way to install Xcode is via the [Mac App Store](https://itunes.apple.com/us/app/xcode/id497799835?mt=12). Installing Xcode will also install the iOS Simulator and all the necessary tools to build your iOS app. @@ -39,14 +64,6 @@ To install a simulator, open Xcode > Preferences... and select [CocoaPods](https://cocoapods.org/) is built with Ruby and it will be installable with the default Ruby available on macOS. -Using the default Ruby available on macOS will require you to use `sudo` when installing gems. (This is only an issue for the duration of the gem installation, though.) - -```shell -sudo gem install cocoapods -``` - -Otherwise you can use a Ruby version manager, such as `rbenv`. Apps created with the command `npx react-native init` described below are configured to work well with `rbenv` and will pick the correct Ruby version requested by the template. - For more information, please visit [CocoaPods Getting Started guide](https://guides.cocoapods.org/using/getting-started.html). @@ -67,6 +84,15 @@ npx react-native init AwesomeProject This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Expo, or if you're adding iOS support to an existing React Native project (see [Integration with Existing Apps](integration-with-existing-apps.md)). You can also use a third-party CLI to init your React Native app, such as [Ignite CLI](https://github.com/infinitered/ignite). +:::info +If you are having trouble with iOS, try to reinstall the dependencies by running: + +1. `cd ios` to navigate to the +2. `bundle install` to install Bundler + 1. If needed: install a [Ruby Version Manager](#ruby) and update the Ruby version +3. `bundle exec pod install` to install the iOS dependencies. + ::: + ### [Optional] Using a specific version or template If you want to start a new project with a specific React Native version, you can use the `--version` argument: From a917b04e8a154bdf99c0cf148feda9f9b1c2c867 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Thu, 15 Sep 2022 14:54:20 +0300 Subject: [PATCH 25/88] Fix broken links to Appendix (#3319) --- docs/new-architecture-library-intro.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/new-architecture-library-intro.md b/docs/new-architecture-library-intro.md index 0d905261fb7..6bad696566e 100644 --- a/docs/new-architecture-library-intro.md +++ b/docs/new-architecture-library-intro.md @@ -126,8 +126,8 @@ When using Flow or TypeScript, you will be using [type annotations](https://flow In general, this means you can use primitive types (strings, numbers, booleans), and function types, object types, and array types. Union types, on the other hand, are not supported. All types must be read-only. For Flow: either `+` or `$ReadOnly<>` or `{||}` objects. For TypeScript: `readonly` for properties, `Readonly<>` for objects, and `ReadonlyArray<>` for arrays. -> See Appendix [I. Flow Type to Native Type Mapping](#i-flow-type-to-native-type-mapping). -> See Appendix [II. TypeScript to Native Type Mapping](#ii-typescript-to-native-type-mapping). +> See Appendix [II. Flow Type to Native Type Mapping](new-architecture-appendix#ii-flow-type-to-native-type-mapping). +> See Appendix [III. TypeScript to Native Type Mapping](new-architecture-appendix#iii-typescript-to-native-type-mapping). ### Codegen Helper Types From 5462afb4e7dcb6ef14272a34418c0e62aa47e0f7 Mon Sep 17 00:00:00 2001 From: Sunny Luo Date: Fri, 16 Sep 2022 16:04:34 +0800 Subject: [PATCH 26/88] fix _getting-started-macos-ios.md info format (#3326) --- docs/_getting-started-macos-ios.md | 4 +++- .../versioned_docs/version-0.70/_getting-started-macos-ios.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/_getting-started-macos-ios.md b/docs/_getting-started-macos-ios.md index 2f5f3eb9699..840b38b5803 100644 --- a/docs/_getting-started-macos-ios.md +++ b/docs/_getting-started-macos-ios.md @@ -85,13 +85,15 @@ npx react-native init AwesomeProject This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Expo, or if you're adding iOS support to an existing React Native project (see [Integration with Existing Apps](integration-with-existing-apps.md)). You can also use a third-party CLI to init your React Native app, such as [Ignite CLI](https://github.com/infinitered/ignite). :::info + If you are having trouble with iOS, try to reinstall the dependencies by running: 1. `cd ios` to navigate to the 2. `bundle install` to install Bundler 1. If needed: install a [Ruby Version Manager](#ruby) and update the Ruby version 3. `bundle exec pod install` to install the iOS dependencies. - ::: + +::: ### [Optional] Using a specific version or template diff --git a/website/versioned_docs/version-0.70/_getting-started-macos-ios.md b/website/versioned_docs/version-0.70/_getting-started-macos-ios.md index 2f5f3eb9699..840b38b5803 100644 --- a/website/versioned_docs/version-0.70/_getting-started-macos-ios.md +++ b/website/versioned_docs/version-0.70/_getting-started-macos-ios.md @@ -85,13 +85,15 @@ npx react-native init AwesomeProject This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Expo, or if you're adding iOS support to an existing React Native project (see [Integration with Existing Apps](integration-with-existing-apps.md)). You can also use a third-party CLI to init your React Native app, such as [Ignite CLI](https://github.com/infinitered/ignite). :::info + If you are having trouble with iOS, try to reinstall the dependencies by running: 1. `cd ios` to navigate to the 2. `bundle install` to install Bundler 1. If needed: install a [Ruby Version Manager](#ruby) and update the Ruby version 3. `bundle exec pod install` to install the iOS dependencies. - ::: + +::: ### [Optional] Using a specific version or template From 7bb5d882995a8a0bd9553bdea8ff2ca4c26ac2d9 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 16 Sep 2022 12:00:23 +0300 Subject: [PATCH 27/88] [0.71.0] Update the New Architecture guide with the changes for the New Template on Android (#3324) Co-authored-by: Riccardo --- docs/build-speed.md | 2 +- docs/new-architecture-app-intro.md | 492 +++++++++++---- docs/new-architecture-app-modules-android.md | 572 ------------------ docs/new-architecture-app-renderer-android.md | 453 -------------- docs/new-architecture-intro.md | 3 - docs/the-new-architecture/use-app-template.md | 11 +- website/sidebars.json | 12 +- website/static/_redirects | 2 + .../version-0.69/build-speed.md | 2 +- .../version-0.70/build-speed.md | 2 +- 10 files changed, 377 insertions(+), 1174 deletions(-) delete mode 100644 docs/new-architecture-app-modules-android.md delete mode 100644 docs/new-architecture-app-renderer-android.md diff --git a/docs/build-speed.md b/docs/build-speed.md index 7cbcacb390c..11f3b46f666 100644 --- a/docs/build-speed.md +++ b/docs/build-speed.md @@ -6,7 +6,7 @@ title: Speeding up your Build phase Building your React Native app could be **expensive** and take several minutes of developers time. This can be problematic as your project grows and generally in bigger organizations with multiple React Native developers. -With [the New React Native Architecture](/docs/next/new-architecture-app-modules-android), this problem is becoming more critical +With [the New React Native Architecture](new-architecture-app-intro), this problem is becoming more critical as you might have to compile some native C++ code in your project with the Android NDK in addition to the native code already necessary for the iOS and Android platforms. To mitigate this performance hit, this page shares some suggestions on how to **improve your build time**. diff --git a/docs/new-architecture-app-intro.md b/docs/new-architecture-app-intro.md index c0d56f91a71..14bf8772a3b 100644 --- a/docs/new-architecture-app-intro.md +++ b/docs/new-architecture-app-intro.md @@ -4,6 +4,8 @@ title: Prerequisites for Applications --- import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; +import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; +import constants from '@site/core/TabsConstants'; @@ -35,128 +37,6 @@ Please [follow the instructions on the React Native website](hermes) to learn ho ::: -## Android - Update Build System - -Using the New Architecture on Android has some prerequisites that you need to meet: - -1. Using Gradle 7.x and Android Gradle Plugin 7.x -2. Using the **new React Gradle Plugin** -3. Building `react-native` **from Source** - -You can update Gradle by running: - -```bash -cd android && ./gradlew wrapper --gradle-version 7.3.3 --distribution-type=all -``` - -While the AGP version should be updated inside the **top-level** `build.gradle` file at the `com.android.tools.build:gradle` dependency line. - -Now, you can edit your **top-level** `settings.gradle` file to include the following line at the end of the file: - -```groovy -includeBuild('../node_modules/react-native-gradle-plugin') - -include(":ReactAndroid") -project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid') -include(":ReactAndroid:hermes-engine") -project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine') -``` - -Then, open the `android/app/src/main/AndroidManifest.xml` file and add this line: - -```diff -android:windowSoftInputMode="adjustResize" -+ android:exported="true"> - -``` - -Then, edit your **top-level Gradle file** to include the highlighted lines: - -```groovy -buildscript { - ext { - buildToolsVersion = "31.0.0" - minSdkVersion = 21 - compileSdkVersion = 31 - targetSdkVersion = 31 - if (System.properties['os.arch'] == "aarch64") { - // For M1 Users we need to use the NDK 24 which added support for aarch64 - ndkVersion = "24.0.8215888" - } else { - // Otherwise we default to the side-by-side NDK version from AGP. - ndkVersion = "21.4.7075529" - } - } - - // ... - dependencies { - // Make sure that AGP is at least at version 7.x - classpath("com.android.tools.build:gradle:7.2.0") - - // Add those lines - classpath("com.facebook.react:react-native-gradle-plugin") - classpath("de.undercouch:gradle-download-task:4.1.2") - } -} -``` - -Edit your **module-level** **Gradle file** (usually `app/build.gradle[.kts]`) to include the following: - -```diff -// ... - -apply plugin: "com.android.application" - -// ... - -if (enableHermes) { -- def hermesPath = "../../node_modules/hermes-engine/android/"; -- debugImplementation files(hermesPath + "hermes-debug.aar") -- releaseImplementation files(hermesPath + "hermes-release.aar") -+ //noinspection GradleDynamicVersion -+ implementation("com.facebook.react:hermes-engine:+") { // From node_modules -+ exclude group:'com.facebook.fbjni' -+ } -} else { - -// ... - -+ configurations.all { -+ resolutionStrategy.dependencySubstitution { -+ substitute(module("com.facebook.react:react-native")) -+ .using(project(":ReactAndroid")) -+ .because("On New Architecture we're building React Native from source") -+ substitute(module("com.facebook.react:hermes-engine")) -+ .using(project(":ReactAndroid:hermes-engine")) -+ .because("On New Architecture we're building Hermes from source") -+ } -+ } - -// Run this once to be able to run the application with BUCK -// puts all compile dependencies into folder libs for BUCK to use -task copyDownloadableDepsToLibs(type: Copy) { - -// ... - -+ def isNewArchitectureEnabled() { -+ // To opt-in for the New Architecture, you can either: -+ // - Set `newArchEnabled` to true inside the `gradle.properties` file -+ // - Invoke gradle with `-newArchEnabled=true` -+ // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` -+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" -+ } -``` - -Finally, it’s time to update your project to use the `react-native` dependency from the source rather than using a precompiled artifact from the NPM package. This is needed as the later setup will rely on building the native code from the source. - -Let’s edit your **module-level** `build.gradle` (the one inside the `app/` folder) and change the following line: - -```diff -dependencies { -- implementation "com.facebook.react:react-native:+" // From node_modules -+ implementation project(":ReactAndroid") // From node_modules -``` - ## iOS - Build the Project After upgrading the project, there are a few changes you need to apply: @@ -257,3 +137,371 @@ The `moduleName` has to be the same string used in the `[RCTRootView initWithBri // Run pod install with the flags RCT_NEW_ARCH_ENABLED=1 pod install ``` + +## Android - Prerequisites + +Using the New Architecture on Android has some prerequisites that you need to meet: + +1. Using Gradle version >= 7.x +2. Using Android Gradle Plugin >= 7.x (i.e. the `com.android.tools.build:gradle` dependency) + +If you updated to React Native 0.68+, you already meet those prerequisites. If you don't meet them, consider updating those dependencies first. + +## Android - React Native Gradle Plugin & Build from Source + +The New Architecture relies on the React Native Gradle Plugin (from the `react-native-gradle-plugin` NPM package) to build and run your project. + +Moreover, in this iteration of the guide you will build React Native from source. + +If you updated your project to React Native 0.68+, you probably already have this configuration set up correctly. + +If not make sure you edit the `android/settings.gradle` file as follows: + +```diff + rootProject.name = 'HelloWorld' + apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) + include ':app' ++includeBuild('../node_modules/react-native-gradle-plugin') + ++include(":ReactAndroid") ++project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid') ++include(":ReactAndroid:hermes-engine") ++project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/+ReactAndroid/hermes-engine') +``` + +Update the `android/build.gradle` file as follows: + +```diff +buildscript { + // ... + dependencies { + + // Add those lines ++ classpath("com.facebook.react:react-native-gradle-plugin") ++ classpath("de.undercouch:gradle-download-task:4.1.2") + } +} +``` + +And update the `android/app/build.gradle` file (please note that this file is different than the top level `build.gradle`) as follows: + +```diff +dependencies { + // ... + if (enableHermes) { +- def hermesPath = "../../node_modules/hermes-engine/android/"; +- debugImplementation files(hermesPath + "hermes-debug.aar") +- releaseImplementation files(hermesPath + "hermes-release.aar") ++ //noinspection GradleDynamicVersion ++ implementation("com.facebook.react:hermes-engine:+") { // From node_modules ++ exclude group:'com.facebook.fbjni' ++ } + } +} + ++ configurations.all { ++ resolutionStrategy.dependencySubstitution { ++ substitute(module("com.facebook.react:react-native")) ++ .using(project(":ReactAndroid")) ++ .because("On New Architecture we're building React Native from source") ++ substitute(module("com.facebook.react:hermes-engine")) ++ .using(project(":ReactAndroid:hermes-engine")) ++ .because("On New Architecture we're building Hermes from source") ++ } ++ } +``` + +## Android - Configure the NDK + +:::caution + +In this iteration of the guide you’re setting up the project to build from source. You might notice an increase in your build time because of this. +You can mitigate this by following the approach described in [Speeding up your Build phase](/docs/next/build-speed) guide. + +::: + +As Codegen will output some Java and some C++ code that needs to build, you need to configure the Android NDK to do so. + +Edit your `android/app/build.gradle` file to include the **two** `externalNativeBuild` blocks detailed below inside the `android{}` block: + +```groovy +android { + defaultConfig { + applicationId "com.awesomeproject" + // ... + + // Add this block + externalNativeBuild { + cmake { + arguments "-DPROJECT_BUILD_DIR=$buildDir", + "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", + "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", + "-DANDROID_STL=c++_shared" + } + } + } + + // Add this block + externalNativeBuild { + cmake { + path "$projectDir/src/main/jni/CMakeLists.txt" + } + } +} +``` + +In the same `build.gradle` file, inside the same `android{}` also add the following section: + +```groovy +android { + // ... + + def reactAndroidProjectDir = project(':ReactAndroid').projectDir + def packageReactNdkLibs = tasks.register("packageReactNdkLibs", Copy) { + dependsOn(":ReactAndroid:packageReactNdkLibsForBuck") + dependsOn("generateCodegenArtifactsFromSchema") + from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib") + into("$buildDir/react-ndk/exported") + } + + afterEvaluate { + preBuild.dependsOn(packageReactNdkLibs) + configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild) + configureCMakeDebug.dependsOn(preDebugBuild) + } + + packagingOptions { + pickFirst '**/libhermes.so' + pickFirst '**/libjsc.so' + } +} +``` + +Finally, you need to create two files that are required to build the native code correctly: + +- A CMake file with the compilation instructions (similar to a `build.gradle` for Android/Java) +- An `OnLoad.cpp` file which, as the name says, will be loaded when your app starts. + +Create a file inside the `android/app/src/main/jni` folder called `CMakeLists.txt` with the following content: + +```cmake title="CMakeLists.txt" +cmake_minimum_required(VERSION 3.13) + +# Define the library name here. +project(appmodules) + +# This file includes all the necessary to let you build your application with the New Architecture. +include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake) +``` + +And create the `android/app/src/main/jni/OnLoad.cpp` file with the following content: + +```cpp title="OnLoad.cpp" +#include +#include +#include +#include +#include + +namespace facebook { +namespace react { + +void registerComponents( + std::shared_ptr registry) { + // Custom Fabric Components go here. You can register custom + // components coming from your App or from 3rd party libraries here. + // + // providerRegistry->add(concreteComponentDescriptorProvider< + // AocViewerComponentDescriptor>()); + + // By default we just use the components autolinked by RN CLI + rncli_registerProviders(registry); +} + +std::shared_ptr provideModules( + const std::string &name, + const JavaTurboModule::InitParams ¶ms) { + // Here you can provide your own module provider for TurboModules coming from + // either your application or from external libraries. The approach to follow + // is similar to the following (for a library called `samplelibrary`): + // + // auto module = samplelibrary_ModuleProvider(moduleName, params); + // if (module != nullptr) { + // return module; + // } + // return rncore_ModuleProvider(moduleName, params); + + // By default we just use the module providers autolinked by RN CLI + return rncli_ModuleProvider(name, params); +} + +} // namespace react +} // namespace facebook + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { + return facebook::jni::initialize(vm, [] { + facebook::react::DefaultTurboModuleManagerDelegate:: + moduleProvidersFromEntryPoint = &facebook::react::provideModules; + facebook::react::DefaultComponentsRegistry:: + registerComponentDescriptorsFromEntryPoint = + &facebook::react::registerComponents; + }); +} +``` + +When the app loads, this file will take care of registering the Native Components and Modules which provide native sources. By default we only provide the autolinked libraries as this allows you to use those libraries. + +This is the only C++ file you'll have to add to your project, and the infrastructure will take care of the rest. + +## Android - Update your Java classes + +To simplify how to enable the New Architecture on Android, you can use some utility classes that will take care of all the setup without you having to worry about it. + +Those classes are all located inside the `com.facebook.react.defaults` package and are all named `Defaults*`. + +### Update the React Native Host + +First, update your `ReactNativeHost` as follows (usually located in your `MainApplication.java` file): + + + + +```diff title="MainApplication.java" ++import com.facebook.react.defaults.DefaultReactNativeHost; + + private final ReactNativeHost mReactNativeHost = +- new ReactNativeHost(this) { ++ new DefaultReactNativeHost(this) { + + @Override + public boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; + } + ++ @Override ++ public boolean isNewArchEnabled() { ++ return true; ++ } +``` + + + + +```diff title="MainApplication.kt" ++import com.facebook.react.defaults.DefaultReactNativeHost + + val reactNativeHost = +- ReactNativeHost(this) { ++ DefaultReactNativeHost(this) { + + override fun getUseDeveloperSupport() = BuildConfig.DEBUG ++ override fun isNewArchEnabled() = true + + } +``` + + + + +### Update the your application OnCreate + +Still inside your `MainApplication` method `onCreate`, make sure that the New Architecture infrastructure is loaded correctly: + + + + +```diff title="MainApplication.java" ++import com.facebook.react.defaults.DefaultNativeEntryPoint; + + @Override + public void onCreate() { + super.onCreate(); + SoLoader.init(this, /* native exopackage */ false); + // Make sure it's called after SoLoader.init ++ ReactFeatureFlags.useTurboModules = true; ++ DefaultNativeEntryPoint.load(); + ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + } +``` + + + + +```diff title="MainApplication.kt" ++import com.facebook.react.defaults.DefaultNativeEntryPoint + + override fun onCreate() { + super.onCreate() + SoLoader.init(this, /* native exopackage */ false) + // Make sure it's called after SoLoader.init ++ ReactFeatureFlags.useTurboModules = true ++ DefaultNativeEntryPoint.load() + ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + } +``` + + + + +### Update your Activity Delegate + +Finally, update your `MainActivity.java` file by providing a React Activity Delegate: + + + + +```diff title="MainActivity.java" ++import com.facebook.react.defaults.DefaultReactActivityDelegate; + +public class MainActivity extends ReactActivity { + ++ @Override ++ protected ReactActivityDelegate createReactActivityDelegate() { ++ return new DefaultReactActivityDelegate( ++ this, ++ getMainComponentName(), ++ true, // Here we enable Fabric ++ true, // Here we enable Concurrent React Features ++ ); ++ } + +} +``` + + + + +```diff title="MainApplication.kt" ++import com.facebook.react.defaults.DefaultReactActivityDelegate; + +public class MainActivity : ReactActivity { + ++ @Override ++ override protected fun createReactActivityDelegate() = ++ DefaultReactActivityDelegate( ++ this, ++ mainComponentName, ++ true, // Here we enable Fabric ++ true, // Here we enable Concurrent React Features ++ ) + +} +``` + + + + +That's it! + +It’s now time to run your Android app to verify that everything works correctly: + +```bash +yarn react-native run-android +``` + +In your Metro terminal log, you will now see the following log to confirm that Fabric is running correctly: + +``` +BUNDLE ./App.js +LOG Running "App" with {"fabric":true,"initialProps":{"concurrentRoot": "true"},"rootTag":1} +``` diff --git a/docs/new-architecture-app-modules-android.md b/docs/new-architecture-app-modules-android.md deleted file mode 100644 index 02069ffac51..00000000000 --- a/docs/new-architecture-app-modules-android.md +++ /dev/null @@ -1,572 +0,0 @@ ---- -id: new-architecture-app-modules-android -title: Enabling TurboModule on Android ---- - -import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; -import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import constants from '@site/core/TabsConstants'; - - - -Make sure your application meets all the [prerequisites](new-architecture-app-intro). - -## 1. Enable NDK and the native build - -:::caution - -In this iteration of the guide we’re setting up the project to let you build from source. You might notice an increase in your build time because of this. -You can mitigate this by following the approach described in [Speeding up your Build phase](/docs/next/build-speed) guide. - -::: - -The Codegen will output some Java and some C++ code that now we need to build. - -Let’s edit your **module-level** `build.gradle` to include the **two** `externalNativeBuild` blocks detailed below inside the `android{}` block: - -```groovy -android { - defaultConfig { - applicationId "com.awesomeproject" - // ... - - // Add this block - externalNativeBuild { - cmake { - arguments "-DPROJECT_BUILD_DIR=$buildDir", - "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", - "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build", - "-DNODE_MODULES_DIR=$rootDir/../node_modules", - "-DANDROID_STL=c++_shared" - } - } - } - - // Add this block - externalNativeBuild { - cmake { - path "$projectDir/src/main/jni/CMakeLists.txt" - } - } -} -``` - -In the same `build.gradle` file, inside the same `android{}` let’s add also the following section: - -```groovy -android { - // ... - - def reactAndroidProjectDir = project(':ReactAndroid').projectDir - def packageReactNdkLibs = tasks.register("packageReactNdkLibs", Copy) { - dependsOn(":ReactAndroid:packageReactNdkLibsForBuck") - dependsOn("generateCodegenArtifactsFromSchema") - from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib") - into("$buildDir/react-ndk/exported") - } - - afterEvaluate { - preBuild.dependsOn(packageReactNdkLibs) - configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild) - configureCMakeDebug.dependsOn(preDebugBuild) - } - - packagingOptions { - pickFirst '**/libhermes.so' - pickFirst '**/libjsc.so' - } -} -``` - -Finally, we need to create a CMake file inside the `src/main/jni` folder called `CMakeLists.txt` with the following content: - -```cmake -cmake_minimum_required(VERSION 3.13) - -# Define the library name here. -project(myapplication_appmodules) - -# This file includes all the necessary to let you build your application with the New Architecture. -include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake) -``` - -This setup will run a native build on your project and will compile the C++ files that have been generated by the codegen. You will see the native build running with the Gradle task `:app:externalNativeBuildDebug` - -You can now verify that everything works correctly by running your android app: - -```bash -yarn react-native run-android -``` - -## 2. Java/Kotlin - Provide a `ReactPackageTurboModuleManagerDelegate` - -Now is time to actually use the Turbo Native Module. -First, we will need to create a `ReactPackageTurboModuleManagerDelegate` subclass, like the following: - - - - -```java -package com.awesomeproject; - -import com.facebook.jni.HybridData; -import com.facebook.react.ReactPackage; -import com.facebook.react.ReactPackageTurboModuleManagerDelegate; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.soloader.SoLoader; - -import java.util.List; - -public class MyApplicationTurboModuleManagerDelegate extends ReactPackageTurboModuleManagerDelegate { - - private static volatile boolean sIsSoLibraryLoaded; - - protected MyApplicationTurboModuleManagerDelegate(ReactApplicationContext reactApplicationContext, List packages) { - super(reactApplicationContext, packages); - } - - protected native HybridData initHybrid(); - - public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder { - protected MyApplicationTurboModuleManagerDelegate build( - ReactApplicationContext context, List packages) { - return new MyApplicationTurboModuleManagerDelegate(context, packages); - } - } - - @Override - protected synchronized void maybeLoadOtherSoLibraries() { - // Prevents issues with initializer interruptions. - if (!sIsSoLibraryLoaded) { - SoLoader.loadLibrary("myapplication_appmodules"); - sIsSoLibraryLoaded = true; - } - } -} -``` - - - - - -```kotlin -package com.awesomeproject - -import com.facebook.jni.HybridData -import com.facebook.react.ReactPackage -import com.facebook.react.ReactPackageTurboModuleManagerDelegate -import com.facebook.react.bridge.ReactApplicationContext -import com.facebook.soloader.SoLoader - -class MyApplicationTurboModuleManagerDelegate -protected constructor( - reactApplicationContext: ReactApplicationContext, - packages: List -) : ReactPackageTurboModuleManagerDelegate(reactApplicationContext, packages) { - - override protected external fun initHybrid(): HybridData? - class Builder : ReactPackageTurboModuleManagerDelegate.Builder() { - override protected fun build( - context: ReactApplicationContext, - packages: List - ): MyApplicationTurboModuleManagerDelegate = - MyApplicationTurboModuleManagerDelegate(context, packages) - } - - @Synchronized - override protected fun maybeLoadOtherSoLibraries() { - // Prevents issues with initializer interruptions. - if (!isSoLibraryLoaded) { - SoLoader.loadLibrary("myapplication_appmodules") - isSoLibraryLoaded = true - } - } - - companion object { - @Volatile private var isSoLibraryLoaded = false - } -} -``` - - - - -Please note that the `SoLoader.loadLibrary` parameter (in this case `"myapplication_appmodules")` should be the same as the one specified for `project()` inside the `CMakeLists.txt` file you created before. - -This class will then be responsible of loading the Turbo Native Modules and will take care of loading the native library build with the NDK at runtime. - -## 3. Adapt your `ReactNativeHost` to use the `ReactPackageTurboModuleManagerDelegate` - -Then, you can provide the class you created to your `ReactNativeHost`. You can locate your `ReactNativeHost` by searching for the `getReactNativeHost()`. The `ReactNativeHost` is usually located inside your `Application` class. - -Once you located it, you need to add the `getReactPackageTurboModuleManagerDelegateBuilder` method as from the snippet below: - - - - -```java -public class MyApplication extends Application implements ReactApplication { - - private final ReactNativeHost mReactNativeHost = - new ReactNativeHost(this) { - @Override - public boolean getUseDeveloperSupport() { /* ... */ } - - @Override - protected List getPackages() { /* ... */ } - - @Override - protected String getJSMainModuleName() {/* ... */ } - - @NonNull - @Override - protected ReactPackageTurboModuleManagerDelegate.Builder getReactPackageTurboModuleManagerDelegateBuilder() { - return new MyApplicationTurboModuleManagerDelegate.Builder(); - } - }; -} -``` - - - - -```kotlin -class MyApplication : Application(), ReactApplication { - private val reactNativeHost: ReactNativeHost = - object : ReactNativeHost(this) { - - override fun getUseDeveloperSupport(): Boolean { - /* ... */ - } - - override fun getPackages(): List? { - /* ... */ - } - - override fun getJSMainModuleName(): String? { - /* ... */ - } - - @NonNull - override fun getReactPackageTurboModuleManagerDelegateBuilder() = - ReactPackageTurboModuleManagerDelegate.Builder() - } -} -``` - - - - -## 4. Extend the `getPackages()` from your `ReactNativeHost` to use the TurboModule - -Still on the `ReactNativeHost` , we need to extend the the `getPackages()` method to include the newly created Turbo Native Module. Update the method to include the following: - - - - -```java -public class MyApplication extends Application implements ReactApplication { - - private final ReactNativeHost mReactNativeHost = - new ReactNativeHost(this) { - @Override - public boolean getUseDeveloperSupport() { /* ... */ } - - @Override - protected List getPackages() { - List packages = new PackageList(this).getPackages(); - - // Add those lines - packages.add(new TurboReactPackage() { - @Nullable - @Override - public NativeModule getModule(String name, ReactApplicationContext reactContext) { - if (name.equals(NativeAwesomeManager.NAME)) { - return new NativeAwesomeManager(reactContext); - } else { - return null; - } - } - - @Override - public ReactModuleInfoProvider getReactModuleInfoProvider() { - return () -> { - final Map moduleInfos = new HashMap<>(); - moduleInfos.put( - NativeAwesomeManager.NAME, - new ReactModuleInfo( - NativeAwesomeManager.NAME, - "NativeAwesomeManager", - false, // canOverrideExistingModule - false, // needsEagerInit - true, // hasConstants - false, // isCxxModule - true // isTurboModule - ) - ); - return moduleInfos; - }; - } - }); - return packages; - } - - @Override - protected String getJSMainModuleName() {/* ... */ } - - @NonNull - @Override - protected ReactPackageTurboModuleManagerDelegate.Builder getReactPackageTurboModuleManagerDelegateBuilder() { - return new MyApplicationTurboModuleManagerDelegate.Builder(); - } - }; -} -``` - - - - -```kotlin -class MyApplication() : Application(), ReactApplication { - - private val reactNativeHost: ReactNativeHost = - object : ReactNativeHost(this) { - override fun getUseDeveloperSupport(): Boolean { - /* ... */ - } - - override protected fun getPackages(): List? { - val packages: MutableList = PackageList(this).getPackages() - - // Add those lines - packages.add( - object : TurboReactPackage() { - @Nullable - override fun getModule( - name: String, - reactContext: ReactApplicationContext? - ): NativeModule? = - if ((name == NativeAwesomeManager.NAME)) { - NativeAwesomeManager(reactContext) - } else { - null - } - - override fun getReactModuleInfoProvider() = - mutableMapOf( - NativeAwesomeManager.NAME, - ReactModuleInfo( - NativeAwesomeManager.NAME, - "NativeAwesomeManager", - false, // canOverrideExistingModule - false, // needsEagerInit - true, // hasConstants - false, // isCxxModule - true // isTurboModule - ) - ) - } - ) - return packages - } - - override protected fun getJSMainModuleName(): String? { - /* ... */ - } - - @NonNull - override protected fun getReactPackageTurboModuleManagerDelegateBuilder(): - ReactPackageTurboModuleManagerDelegate.Builder? { - return Builder() - } - } -} -``` - - - - -## 5. C++ Provide a native implementation for the methods in your `*TurboModuleDelegate` class - -If you take a closer look at the class `MyApplicationTurboModuleManagerDelegate` that you created before, you will notice how some of the methods are `native`. - -Therefore, you need to provide some C++ classes to implement those methods. Specifically you will need those files, to be added inside the `src/main/jni` folder: - -- `MyApplicationTurboModuleManagerDelegate.h` An header file for the TurboModule Delegate. -- `MyApplicationTurboModuleManagerDelegate.cpp` The implementation of the aforementioned header file. -- `MyApplicationModuleProvider.h` A header file for the TurboModule provider, where you can specify which TurboModules you want to load. -- `MyApplicationModuleProvider.cpp` The implementation for the aforementioned header file. -- `OnLoad.cpp` Where the initialisation code will be placed. Specifically TurboModule uses FBJNI so the initialisation for such library lives there. - -The content of those files should be the following: - -#### MyApplicationTurboModuleManagerDelegate.h - -Please note that the `kJavaDescriptor` should be adapted to follow the package name you picked for your project. - -```cpp -#include -#include - -#include -#include - -namespace facebook { -namespace react { - -class MyApplicationTurboModuleManagerDelegate : public jni::HybridClass { -public: - // Adapt it to the package you used for your Java class. - static constexpr auto kJavaDescriptor = - "Lcom/awesomeproject/MyApplicationTurboModuleManagerDelegate;"; - - static jni::local_ref initHybrid(jni::alias_ref); - - static void registerNatives(); - - std::shared_ptr getTurboModule(const std::string name, const std::shared_ptr jsInvoker) override; - std::shared_ptr getTurboModule(const std::string name, const JavaTurboModule::InitParams ¶ms) override; - -private: - friend HybridBase; - using HybridBase::HybridBase; - -}; - -} // namespace react -} // namespace facebook -``` - -#### MyApplicationTurboModuleManagerDelegate.cpp - -```cpp -#include "MyApplicationTurboModuleManagerDelegate.h" -#include "MyApplicationModuleProvider.h" - -namespace facebook { -namespace react { - -jni::local_ref MyApplicationTurboModuleManagerDelegate::initHybrid(jni::alias_ref) { - return makeCxxInstance(); -} - -void MyApplicationTurboModuleManagerDelegate::registerNatives() { - registerHybrid({ - makeNativeMethod("initHybrid", MyApplicationTurboModuleManagerDelegate::initHybrid), - }); -} - -std::shared_ptr MyApplicationTurboModuleManagerDelegate::getTurboModule(const std::string name, const std::shared_ptr jsInvoker) { - // Not implemented yet: provide pure-C++ NativeModules here. - return nullptr; -} - -std::shared_ptr MyApplicationTurboModuleManagerDelegate::getTurboModule(const std::string name, const JavaTurboModule::InitParams ¶ms) { - return MyApplicationModuleProvider(name, params); -} - -} // namespace react -} // namespace facebook -``` - -#### MyApplicationModuleProvider.h - -```cpp -#pragma once - -#include -#include - -#include - -namespace facebook { -namespace react { - -std::shared_ptr MyApplicationModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms); - -} // namespace react -} // namespace facebook -``` - -#### MyApplicationModuleProvider.cpp - -Please adapt the `samplelibrary.h` import to match the same library name you provided when building the apps. -This is the C++ generated file that is created by the codegen. - -Here you can also specify more than one provider, should you have more than one Turbo Native Module. Specifically in this example we look for a Turbo Native Module from `samplelibrary` (the one we specified) and we fallback to the `rncore` Module Provider (containing all the Core modules). - -```cpp -#include "MyApplicationModuleProvider.h" - -#include -#include - -namespace facebook { -namespace react { - -std::shared_ptr MyApplicationModuleProvider(const std::string moduleName, const JavaTurboModule::InitParams ¶ms) { - auto module = samplelibrary_ModuleProvider(moduleName, params); - if (module != nullptr) { - return module; - } - - return rncore_ModuleProvider(moduleName, params); -} - -} // namespace react -} // namespace facebook -``` - -#### OnLoad.cpp - -```cpp -#include -#include "MyApplicationTurboModuleManagerDelegate.h" - -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { - return facebook::jni::initialize(vm, [] { - facebook::react::MyApplicationTurboModuleManagerDelegate::registerNatives(); - }); -} -``` - -## 6. Enable the `useTurboModules` flag in your Application `onCreate` - -Now you can finally enable the `Turbo Native Module` support in your Application. To do so, you need to turn on the `useTurboModule` flag inside your Application `onCreate` method. - - - - -```java -public class MyApplication extends Application implements ReactApplication { - - @Override - public void onCreate() { - ReactFeatureFlags.useTurboModules = true; - //... - } -} -``` - - - - - -```kotlin -class MyApplication : Application(), ReactApplication { - - override fun onCreate() { - ReactFeatureFlags.useTurboModules = true - // ... - } -} -``` - - - - -It’s now time to run again your Android app to verify that everything works correctly: - -```bash -yarn react-native run-android -``` diff --git a/docs/new-architecture-app-renderer-android.md b/docs/new-architecture-app-renderer-android.md deleted file mode 100644 index 39bb732efbf..00000000000 --- a/docs/new-architecture-app-renderer-android.md +++ /dev/null @@ -1,453 +0,0 @@ ---- -id: new-architecture-app-renderer-android -title: Enabling Fabric on Android ---- - -import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; - - - -Make sure your application meets all the [prerequisites](new-architecture-app-intro). - -## 1. Provide a `JSIModulePackage` inside your `ReactNativeHost` - -In order to enable Fabric in your app, you would need to add a `JSIModulePackage` inside your `ReactNativeHost`. If you followed the TurboModule section of this guide, you probably already know where to find your `ReactNativeHost`. If not, you can locate your `ReactNativeHost` by searching for the `getReactNativeHost()`. The `ReactNativeHost` is usually located inside your `Application` class. - -Once you located it, you need to add the `getJSIModulePackage` method as from the snippet below: - -```java title='MyApplication.java' -public class MyApplication extends Application implements ReactApplication { - - private final ReactNativeHost mReactNativeHost = - new ReactNativeHost(this) { - - // Add those lines: - @Nullable - @Override - protected JSIModulePackage getJSIModulePackage() { - return new JSIModulePackage() { - @Override - public List getJSIModules( - final ReactApplicationContext reactApplicationContext, - final JavaScriptContextHolder jsContext) { - final List specs = new ArrayList<>(); - specs.add(new JSIModuleSpec() { - @Override - public JSIModuleType getJSIModuleType() { - return JSIModuleType.UIManager; - } - - @Override - public JSIModuleProvider getJSIModuleProvider() { - final ComponentFactory componentFactory = new ComponentFactory(); - CoreComponentsRegistry.register(componentFactory); - final ReactInstanceManager reactInstanceManager = getReactInstanceManager(); - - ViewManagerRegistry viewManagerRegistry = - new ViewManagerRegistry( - reactInstanceManager.getOrCreateViewManagers( - reactApplicationContext)); - - return new FabricJSIModuleProvider( - reactApplicationContext, - componentFactory, - new EmptyReactNativeConfig(), - viewManagerRegistry); - } - }); - return specs; - } - }; - } - }; -} -``` - -## 2. Make sure your call `setIsFabric` on your Activity’s `ReactRootView` - -Inside your `Activity` class, you need to make sure you’re calling `setIsFabric` on the `ReactRootView`. -If you don’t have a `ReactActivityDelegate` you might need to create one. - -```java -public class MainActivity extends ReactActivity { - - // Add the Activity Delegate, if you don't have one already. - public static class MainActivityDelegate extends ReactActivityDelegate { - - public MainActivityDelegate(ReactActivity activity, String mainComponentName) { - super(activity, mainComponentName); - } - - @Override - protected ReactRootView createRootView() { - ReactRootView reactRootView = new ReactRootView(getContext()); - - // Make sure to call setIsFabric(true) on your ReactRootView - reactRootView.setIsFabric(true); - return reactRootView; - } - } - - // Make sure to override the `createReactActivityDelegate()` method. - @Override - protected ReactActivityDelegate createReactActivityDelegate() { - return new MainActivityDelegate(this, getMainComponentName()); - } -} -``` - -The crucial part in this code is the `reactRootView.setIsFabric(true)` which will enable the new renderer for this Activity. - -You can now verify that everything works correctly by running your android app: - -```bash -yarn react-native run-android -``` - -In your Metro terminal log, you will now see the following log to confirm that Fabric is running correctly: - -``` -BUNDLE ./App.js -LOG Running "App" with {"fabric":true,"initialProps":{},"rootTag":1} -``` - -## Migrating Android ViewManagers - -First, make sure you followed the instructions to [Enabling the New Renderer (Fabric) in Your Android Application](#enabling-the-new-renderer-fabric-in-your-android-application). Plus we will also assume that you followed the instructions from [Enabling the New NativeModule System (Turbo Module) in Your Android Application](#enabling-the-new-nativemodule-system-turbomodule-in-your-android-application) as the native builds setup steps are presented over there and won’t be repeated here. - -### JavaScript changes - -1. Make sure your other JS changes are ready to go by following Preparing your JavaScript codebase for the new React Native Renderer (Fabric) -2. Replace the call to `requireNativeComponent` with `codegenNativeComponent`. This tells the JS codegen to start generating the native implementation of the component, consisting of C++ and Java classes. This is how it looks for the WebView component: - -```ts -import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; - -// babel-plugin-codegen will replace the function call to use NativeComponentRegistry -// 'RCTWebView' is interopped by RCTFabricComponentsPlugins - -export default (codegenNativeComponent( - 'RCTWebView', -): HostComponent); -``` - -4. **[Flow users]** Make sure your native component has Flow types for its props, since the JS codegen uses these types to generate the type-safe native implementation of the component. The codegen generates C++ classes during the build time, which guarantees that the native implementation is always up-to-date with its JS interface. Use [these c++ compatible types](https://github.com/facebook/react-native/blob/main/Libraries/Types/CodegenTypes.js#L28-L30). - -```ts title="RNTMyNativeViewNativeComponent.js" -import type {Int32} from 'react-native/Libraries/Types/CodegenTypes'; -import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; -import type {HostComponent} from 'react-native'; -import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes'; - -type NativeProps = $ReadOnly<{| - ...ViewProps, // This is required. - someNumber: Int32, -|}>; - -[...] - -export default (codegenNativeComponent( - 'RNTMyNativeView', -): HostComponent); -``` - -5. **[TypeScript users]** We are currently investigating a support for TypeScript. - -### Native/Java Changes - -1. **Update (or Create) your ViewManager to use the generated classes from the Codegen.** - -Specifically you will have to implement the generated **ViewManagerInterface** and to pass events to the generated **ViewManagerDelegate.** -Your ViewManager could follow this structure. The MyNativeView class in this example is an Android View implementation (like a subclass of LinearLayout, Button, TextView, etc.) - -```java title='MyNativeViewManager.java' -// View manager for MyNativeView components. -@ReactModule(name = MyNativeViewManager.REACT_CLASS) -public class MyNativeViewManager extends SimpleViewManager - implements RNTMyNativeViewManagerInterface { - - public static final String REACT_CLASS = "RNTMyNativeView"; - - private final ViewManagerDelegate mDelegate; - - public MyNativeViewManager() { - mDelegate = new RNTMyNativeViewManagerDelegate<>(this); - } - - @Nullable - @Override - protected ViewManagerDelegate getDelegate() { - return mDelegate; - } - - @NonNull - @Override - public String getName() { - return REACT_CLASS; - } - - @NonNull - @Override - protected MyNativeView createViewInstance(@NonNull ThemedReactContext reactContext) { - return new MyNativeView(reactContext); - } -} -``` - -1. **Add your ViewManager to one of the Packages loaded by your Application.** - -Specifically inside the `ReactNativeHost` , update `getPackages` method to include the following: - -```java -public class MyApplication extends Application implements ReactApplication { - - private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { - @Override - public boolean getUseDeveloperSupport() { /* ... */ } - - @Override - protected List getPackages() { - List packages = new PackageList(this).getPackages(); - - // ... other packages or `TurboReactPackage added` here... - - // Add those lines. - packages.add(new ReactPackage() { - @NonNull - @Override - public List createNativeModules( - @NonNull ReactApplicationContext reactContext) { - return Collections.emptyList(); - } - - @NonNull - @Override - public List createViewManagers( - @NonNull ReactApplicationContext reactContext) { - // Your ViewManager is returned here. - return Collections.singletonList(new MyNativeViewManager()); - } - }); - return packages; - } - }; -} -``` - -3. **Add a Fabric Component Registry** - -You need to create a new component Registry that will allow you to **register** your components to be discovered by Fabric. Let’s create the `MyComponentsRegistry` file with the following content. - -As you can see, some methods are `native()` which we will implement in C++ in the following paragraph. - -```java -package com.awesomeproject; - -import com.facebook.jni.HybridData; -import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.react.fabric.ComponentFactory; -import com.facebook.soloader.SoLoader; - -@DoNotStrip -public class MyComponentsRegistry { - static { - SoLoader.loadLibrary("fabricjni"); - } - - @DoNotStrip private final HybridData mHybridData; - - @DoNotStrip - private native HybridData initHybrid(ComponentFactory componentFactory); - - @DoNotStrip - private MyComponentsRegistry(ComponentFactory componentFactory) { - mHybridData = initHybrid(componentFactory); - } - - @DoNotStrip - public static MyComponentsRegistry register(ComponentFactory componentFactory) { - return new MyComponentsRegistry(componentFactory); - } -} -``` - -4. **Register your custom Fabric Component Registry** - -Finally, let’s edit the `getJSIModulePackage` from the `ReactNativeHost` to also register your Component Registry alongside the Core one: - -```java -public class MyApplication extends Application implements ReactApplication { - - private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { - @Nullable - @Override - protected JSIModulePackage getJSIModulePackage() { - return new JSIModulePackage() { - @Override - public List getJSIModules( - final ReactApplicationContext reactApplicationContext, - final JavaScriptContextHolder jsContext) { - final List specs = new ArrayList<>(); - specs.add(new JSIModuleSpec() { - // ... - - @Override - public JSIModuleProvider getJSIModuleProvider() { - final ComponentFactory componentFactory = new ComponentFactory(); - CoreComponentsRegistry.register(componentFactory); - - // Add this line just below CoreComponentsRegistry.register - MyComponentsRegistry.register(componentFactory); - - // ... - } - }); - return specs; - } - }; - } - }; -} -``` - -### Native/C++ Changes - -It’s now time to provide an implementation for your `MyComponentsRegistry` in C++: - -1. **Create a header file: `MyComponentsRegistry.h`** - -The file should be placed inside the `src/main/jni` folder. -Please note that the `kJavaDescriptor` should be adapted to follow the package name you picked for your project. - -```cpp title="MyComponentsRegistry.h" -#pragma once - -#include -#include -#include -#include - -namespace facebook { -namespace react { - -class MyComponentsRegistry - : public facebook::jni::HybridClass { - public: - constexpr static auto kJavaDescriptor = - "Lcom/awesomeproject/MyComponentsRegistry;"; - - static void registerNatives(); - - MyComponentsRegistry(ComponentFactory *delegate); - - private: - friend HybridBase; - - static std::shared_ptr - sharedProviderRegistry(); - - const ComponentFactory *delegate_; - - static jni::local_ref initHybrid( - jni::alias_ref, - ComponentFactory *delegate); -}; - -} // namespace react -} // namespace facebook -``` - -2. **Create an implementation file: `MyComponentsRegistry.cpp`** - -The file should be placed inside the `src/main/jni` folder alongside `MyComponentsRegistry.h - -```cpp title="MyComponentsRegistry.cpp" -#include "MyComponentsRegistry.h" - -#include -#include -#include -#include -#include - -namespace facebook { -namespace react { - -MyComponentsRegistry::MyComponentsRegistry( - ComponentFactory *delegate) - : delegate_(delegate) {} - -std::shared_ptr -MyComponentsRegistry::sharedProviderRegistry() { - auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); - - providerRegistry->add(concreteComponentDescriptorProvider< - RNTMyNativeViewComponentDescriptor>()); - - return providerRegistry; -} - -jni::local_ref -MyComponentsRegistry::initHybrid( - jni::alias_ref, - ComponentFactory *delegate) { - auto instance = makeCxxInstance(delegate); - - auto buildRegistryFunction = - [](EventDispatcher::Weak const &eventDispatcher, - ContextContainer::Shared const &contextContainer) - -> ComponentDescriptorRegistry::Shared { - auto registry = MyComponentsRegistry::sharedProviderRegistry() - ->createComponentDescriptorRegistry( - {eventDispatcher, contextContainer}); - - auto mutableRegistry = - std::const_pointer_cast(registry); - - mutableRegistry->setFallbackComponentDescriptor( - std::make_shared( - ComponentDescriptorParameters{ - eventDispatcher, contextContainer, nullptr})); - - return registry; - }; - - delegate->buildRegistryFunction = buildRegistryFunction; - return instance; -} - -void MyComponentsRegistry::registerNatives() { - registerHybrid({ - makeNativeMethod("initHybrid", MyComponentsRegistry::initHybrid), - }); -} - -} // namespace react -} // namespace facebook -``` - -4. **Load your file in the OnLoad.cpp** - -If you followed the TurboModule instructions, you should have a `OnLoad.cpp` file inside the `src/main/jni` folder. There you should add a line to load the `MyComponentsRegistry` class: - -```cpp title="OnLoad.cpp" -#include -#include "MyApplicationTurboModuleManagerDelegate.h" -// Add this import -#include "MyComponentsRegistry.h" - -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { - return facebook::jni::initialize(vm, [] { - facebook::react::MyApplicationTurboModuleManagerDelegate::registerNatives(); - - // Add this line - facebook::react::MyComponentsRegistry::registerNatives(); - }); -} -``` - -You can now verify that everything works correctly by running your android app: - -```bash -yarn react-native run-android -``` diff --git a/docs/new-architecture-intro.md b/docs/new-architecture-intro.md index e5b224a1649..277e9d2e81e 100644 --- a/docs/new-architecture-intro.md +++ b/docs/new-architecture-intro.md @@ -22,9 +22,6 @@ The guide is divided into five sections: - [iOS](new-architecture-library-ios) - **Supporting the New Architecture in your App** - [Prerequisites for Supporting the New Architecture in your App](new-architecture-app-intro) - - Android - - [Enabling the New Native Module System (Turbo Module) in your App](new-architecture-app-modules-android) - - [Enabling the New Renderer (Fabric) in your App](new-architecture-app-renderer-android) - [**React 18 & React Native**](react-18-and-react-native) - [**Troubleshooting**](new-architecture-troubleshooting) - [**Appendix**](new-architecture-appendix) diff --git a/docs/the-new-architecture/use-app-template.md b/docs/the-new-architecture/use-app-template.md index 53f96acc3f6..2fdfdf55fee 100644 --- a/docs/the-new-architecture/use-app-template.md +++ b/docs/the-new-architecture/use-app-template.md @@ -119,13 +119,4 @@ After you build and run the app when Metro serves the JavaScript bundle, you sho If you'd like to view the code changes relevant to the New Architecture, take a look at the [upgrade helper from version 0.67.4 to 0.68.0](https://react-native-community.github.io/upgrade-helper/?from=0.67.4&to=0.68.0). Files that were added for the New Architecture are marked with a yellow banner. -For further explanations of what each file is doing, check out these guides to walk through the changes step-by-step: - -#### Android - -- [Enabling the New Native Module System (Turbo Module) on Android](new-architecture-app-modules-android.md) -- [Enabling the New Renderer (Fabric) on Android](new-architecture-app-renderer-android.md) - -#### iOS - -- [Enabling The New Architecture in Your App](new-architecture-app-intro.md) +For further explanations of what each file is doing, check out these guides to walk through the changes step-by-step: [Enabling The New Architecture in Your App](new-architecture-app-intro.md) diff --git a/website/sidebars.json b/website/sidebars.json index 504f2d8947a..3bf2d97e9f0 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -122,17 +122,7 @@ "new-architecture-library-ios" ] }, - { - "type": "category", - "label": "Supporting in your App", - "collapsible": false, - "collapsed": false, - "items": [ - "new-architecture-app-intro", - "new-architecture-app-modules-android", - "new-architecture-app-renderer-android" - ] - }, + "new-architecture-app-intro", "react-18-and-react-native", "new-architecture-troubleshooting", "new-architecture-appendix" diff --git a/website/static/_redirects b/website/static/_redirects index d5fa4b353c5..1d7ba174410 100644 --- a/website/static/_redirects +++ b/website/static/_redirects @@ -16,6 +16,8 @@ /blog/2021/03/11/version-0.64 /blog/2021/03/12/version-0.64 # Removed pages +/docs/new-architecture-app-modules-android /docs/new-architecture-intro +/docs/new-architecture-app-renderer-android /docs/new-architecture-intro /docs/new-architecture-app-modules-ios /docs/new-architecture-intro /docs/new-architecture-app-renderer-ios /docs/new-architecture-intro diff --git a/website/versioned_docs/version-0.69/build-speed.md b/website/versioned_docs/version-0.69/build-speed.md index 4eebf969d66..7cb71e375ab 100644 --- a/website/versioned_docs/version-0.69/build-speed.md +++ b/website/versioned_docs/version-0.69/build-speed.md @@ -6,7 +6,7 @@ title: Speeding up your Build phase Building your React Native app could be **expensive** and take several minutes of developers time. This can be problematic as your project grows and generally in bigger organizations with multiple React Native developers. -With [the New React Native Architecture](/docs/next/new-architecture-app-modules-android), this problem is becoming more critical +With [the New React Native Architecture](new-architecture-app-modules-android), this problem is becoming more critical as you might have to compile some native C++ code in your project with the Android NDK in addition to the native code already necessary for the iOS and Android platforms. To mitigate this performance hit, this page shares some suggestions on how to **improve your build time**. diff --git a/website/versioned_docs/version-0.70/build-speed.md b/website/versioned_docs/version-0.70/build-speed.md index 7cbcacb390c..129423924d4 100644 --- a/website/versioned_docs/version-0.70/build-speed.md +++ b/website/versioned_docs/version-0.70/build-speed.md @@ -6,7 +6,7 @@ title: Speeding up your Build phase Building your React Native app could be **expensive** and take several minutes of developers time. This can be problematic as your project grows and generally in bigger organizations with multiple React Native developers. -With [the New React Native Architecture](/docs/next/new-architecture-app-modules-android), this problem is becoming more critical +With [the New React Native Architecture](new-architecture-app-modules-android), this problem is becoming more critical as you might have to compile some native C++ code in your project with the Android NDK in addition to the native code already necessary for the iOS and Android platforms. To mitigate this performance hit, this page shares some suggestions on how to **improve your build time**. From 8c65a420c02b9c77f57aaa649a27eda941b5a290 Mon Sep 17 00:00:00 2001 From: Lorenzo Sciandra Date: Fri, 16 Sep 2022 11:19:11 +0100 Subject: [PATCH 28/88] minor tweaks to the wording for the versions page (#3327) --- website/src/pages/versions.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/website/src/pages/versions.js b/website/src/pages/versions.js index dddd45a2eb5..36a8117bfc4 100644 --- a/website/src/pages/versions.js +++ b/website/src/pages/versions.js @@ -60,21 +60,18 @@ const Versions = () => {

React Native versions

- Open source React Native releases follow a monthly release train that is + Open source React Native releases follow a release train that is coordinated on GitHub through the{' '} + href={'https://github.com/reactwg/react-native-releases/discussions'}> react-native-releases {' '} - repository. At the beginning of each month, a new release candidate is - created off the main branch of{' '} + repository. New releases are created off the main branch of{' '} facebook/react-native - . The release candidate will soak for a month to allow contributors like - yourself to{' '} + . They will follow a Release Candidate process to allow contributors + like yourself to{' '} verify the changes and to identify any issues by{' '} From 5dd8fcd914f187bfe686f5dabc59326efae0a900 Mon Sep 17 00:00:00 2001 From: Lorenzo Sciandra Date: Fri, 16 Sep 2022 18:27:40 +0100 Subject: [PATCH 29/88] showcase: update entries (#3328) --- website/showcase.json | 82 +++++++++++++++----- website/static/img/showcase/bolt.png | Bin 0 -> 137267 bytes website/static/img/showcase/dave.png | Bin 0 -> 142770 bytes website/static/img/showcase/klarna.jpg | Bin 0 -> 9842 bytes website/static/img/showcase/mattermost.webp | Bin 0 -> 20760 bytes website/static/img/showcase/openvpn.png | Bin 0 -> 24551 bytes website/static/img/showcase/playstation.png | Bin 0 -> 33010 bytes website/static/img/showcase/puma.png | Bin 0 -> 9455 bytes website/static/img/showcase/wordpress.png | Bin 0 -> 99297 bytes 9 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 website/static/img/showcase/bolt.png create mode 100644 website/static/img/showcase/dave.png create mode 100644 website/static/img/showcase/klarna.jpg create mode 100644 website/static/img/showcase/mattermost.webp create mode 100644 website/static/img/showcase/openvpn.png create mode 100644 website/static/img/showcase/playstation.png create mode 100644 website/static/img/showcase/puma.png create mode 100644 website/static/img/showcase/wordpress.png diff --git a/website/showcase.json b/website/showcase.json index 4bbd69ca6c3..3e8d0aa61c5 100644 --- a/website/showcase.json +++ b/website/showcase.json @@ -11,8 +11,7 @@ "name": "Facebook Ads Manager", "icon": "adsmanager.png", "linkAppStore": "https://apps.apple.com/us/app/facebook-ads-manager/id964397083", - "linkPlayStore": "https://play.google.com/store/apps/details?id=com.facebook.adsmanager", - "pinned": true + "linkPlayStore": "https://play.google.com/store/apps/details?id=com.facebook.adsmanager" }, { "name": "Oculus", @@ -64,8 +63,7 @@ "name": "Shopify", "icon": "shopify.png", "linkAppStore": "https://apps.apple.com/us/app/shopify-your-ecommerce-store/id371294472", - "linkPlayStore": "https://play.google.com/store/apps/details?id=com.shopify.mobile&hl=en_US&gl=US", - "pinned": true + "linkPlayStore": "https://play.google.com/store/apps/details?id=com.shopify.mobile&hl=en_US&gl=US" }, { "name": "Shop: All your favorite brands", @@ -97,6 +95,41 @@ "infoTitle": "Onboarding thousands of users with React Native", "pinned": true }, + { + "name": "PUMA", + "icon": "puma.png", + "linkAppStore": "https://apps.apple.com/us/app/puma/id1563024677", + "linkPlayStore": "https://play.google.com/store/apps/details?id=com.puma.ecom.app", + "pinned": true + }, + { + "name": "PlayStation App", + "icon": "playstation.png", + "linkAppStore": "https://apps.apple.com/gb/app/playstation-app/id410896080", + "linkPlayStore": "https://play.google.com/store/apps/details?id=com.scee.psxandroid", + "pinned": true + }, + { + "name": "OpenVPN Connect", + "icon": "openvpn.png", + "linkAppStore": "https://apps.apple.com/us/app/openvpn-connect/id590379981", + "linkPlayStore": "https://play.google.com/store/apps/details?id=net.openvpn.openvpn" + }, + { + "name": "WordPress - Website Builder", + "icon": "wordpress.png", + "linkAppStore": "https://apps.apple.com/app/apple-store/id335703880", + "linkPlayStore": "https://play.google.com/store/apps/details?id=org.wordpress.android", + "infoLink": "https://github.com/wordpress-mobile/gutenberg-mobile", + "infoTitle": "Learn more", + "pinned": true + }, + { + "name": "Dave - Banking & Cash Advance", + "icon": "dave.png", + "linkAppStore": "https://apps.apple.com/US/app/id1193801909", + "linkPlayStore": "https://play.google.com/store/apps/details?id=com.dave" + }, { "name": "Tableau", "icon": "tableau.webp", @@ -129,8 +162,7 @@ "linkAppStore": "https://apps.apple.com/us/app/nerdwallet/id1174471607", "linkPlayStore": "https://play.google.com/store/apps/details?id=com.mobilecreditcards&hl=en_US", "infoLink": "https://www.nerdwallet.com/blog/engineering/beyond-the-browser-how-nerdwallet-went-native/", - "infoTitle": "Beyond the Browser: How NerdWallet Went Native", - "pinned": true + "infoTitle": "Beyond the Browser: How NerdWallet Went Native" }, { "name": "Discord", @@ -183,17 +215,7 @@ "linkAppStore": "https://itunes.apple.com/us/app/wix-com/id1099748482?mt=8", "linkPlayStore": "https://play.google.com/store/apps/details?id=com.wix.android", "infoLink": "https://medium.com/wix-engineering/react-native-at-wix-the-architecture-db6361764da6", - "infoTitle": "React Native at Wix — The Architecture", - "pinned": true - }, - { - "name": "Salesforce", - "icon": "salesforce.png", - "linkAppStore": "https://apps.apple.com/us/app/salesforce/id404249815", - "linkPlayStore": "https://play.google.com/store/apps/details?id=com.salesforce.chatter", - "infoLink": "https://www.salesforce.com/products/einstein/einstein-voice/", - "infoTitle": "Einstein Voice Assistant: Voice Activated AI", - "pinned": true + "infoTitle": "React Native at Wix — The Architecture" }, { "name": "Words with Friends 2", @@ -201,8 +223,7 @@ "linkAppStore": "https://apps.apple.com/app/words-with-friends-2-word-game/id1196764367", "linkPlayStore": "https://play.google.com/store/apps/details?id=com.zynga.words3&hl=en_US&gl=US", "infoLink": "https://medium.com/zynga-engineering/why-how-words-with-friends-is-adopting-react-native-b24a405f421c", - "infoTitle": "Why & How Words With Friends Is Adopting React Native", - "pinned": true + "infoTitle": "Why & How Words With Friends Is Adopting React Native" }, { "name": "Call of Duty Companion App", @@ -210,8 +231,7 @@ "linkAppStore": "https://apps.apple.com/us/app/call-of-duty-companion-app/id1405837628", "linkPlayStore": "https://play.google.com/store/apps/details?id=com.activision.callofduty.companion", "infoLink": "https://www.callofduty.com/app", - "infoTitle": "", - "pinned": true + "infoTitle": "" }, { "name": "Foreca", @@ -276,6 +296,26 @@ "infoLink": "https://www.tencent.com/en-us/business.html", "infoTitle": "QQ is China's largest messaging platform, with over 829 million active accounts", "pinned": true + }, + { + "name": "Bolt Food: Delivery & Takeaway", + "icon": "bolt.png", + "linkAppStore": "https://apps.apple.com/us/app/bolt-food/id1451492388", + "linkPlayStore": "https://play.google.com/store/apps/details?id=com.bolt.deliveryclient", + "infoLink": "https://medium.com/bolt-labs/how-we-built-a-react-native-app-in-2-months-aeadf210a764" + }, + { + "name": "Mattermost", + "icon": "mattermost.webp", + "linkAppStore": "https://apps.apple.com/us/app/mattermost/id1257222717", + "linkPlayStore": "https://play.google.com/store/apps/details?id=com.mattermost.rn", + "infoLink": "https://github.com/mattermost/mattermost-mobile" + }, + { + "name": "Klarna | Shop now. Pay later.", + "icon": "klarna.jpg", + "linkAppStore": "https://apps.apple.com/us/app/klarna-shop-now-pay-later/id1115120118", + "linkPlayStore": "https://play.google.com/store/apps/details?id=com.myklarnamobile" } ] } diff --git a/website/static/img/showcase/bolt.png b/website/static/img/showcase/bolt.png new file mode 100644 index 0000000000000000000000000000000000000000..d538043842cb86e32020a86cee43851cf3187424 GIT binary patch literal 137267 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ΞF&nM8Xr0OcoST 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 R)n6v^-`#&E1Q-wd{|C)$h*$ss literal 0 HcmV?d00001 diff --git a/website/static/img/showcase/mattermost.webp b/website/static/img/showcase/mattermost.webp new file mode 100644 index 0000000000000000000000000000000000000000..b4501db90c97e45add9c19fcdc0324ff7bd75507 GIT binary patch literal 20760 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 literal 0 HcmV?d00001 diff --git a/website/static/img/showcase/playstation.png b/website/static/img/showcase/playstation.png new file mode 100644 index 0000000000000000000000000000000000000000..6af8f5c30ca85d4f903a8d5ea5ca6be38a7e31db GIT binary patch literal 33010 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 literal 0 HcmV?d00001 diff --git a/website/static/img/showcase/wordpress.png b/website/static/img/showcase/wordpress.png new file mode 100644 index 0000000000000000000000000000000000000000..adb8e1530f762eee7108d86baea4e505254d7507 GIT binary patch literal 99297 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 P7=Xaj)z4*}Q$iB}rVCXI literal 0 HcmV?d00001 From 7202412aec9f52de63926ce73c473676ec6f8ceb Mon Sep 17 00:00:00 2001 From: Bartosz Kaszubowski Date: Tue, 20 Sep 2022 00:35:29 +0200 Subject: [PATCH 30/88] fix incorrect link to re-enable prod deploy (#3330) --- website/versioned_docs/version-0.68/build-speed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/versioned_docs/version-0.68/build-speed.md b/website/versioned_docs/version-0.68/build-speed.md index ebd3d46151f..94a1a7a8ce0 100644 --- a/website/versioned_docs/version-0.68/build-speed.md +++ b/website/versioned_docs/version-0.68/build-speed.md @@ -6,7 +6,7 @@ title: Speeding up your Build phase Building your React Native app could be **expensive** and take several minutes of developers time. This can be problematic as your project grows and generally in bigger organizations with multiple React Native developers. -With [the New React Native Architecture](/docs/next/new-architecture-app-modules-android), this problem is becoming more critical +With [the New React Native Architecture](/docs/new-architecture-app-modules-android), this problem is becoming more critical as you might have to compile some native C++ code in your project with the Android NDK in addition to the native code already necessary for the iOS and Android platforms. To mitigate this performance hit, this page shares some suggestions on how to **improve your build time**. From 72c8bd5f749ec7d3256af651a7ea1ed3ebd5a9c1 Mon Sep 17 00:00:00 2001 From: Lorenzo Sciandra Date: Tue, 20 Sep 2022 18:34:32 +0100 Subject: [PATCH 31/88] Modify the top navbar to be less full (#3177) * modify navbar * rename * reorder and rename * reorder the navbar * change size to match the other elements * change style to match the other elements * tweak the footer to reflect the new header * fix link * fix the other link * small CSS tweaks * small naming tweak Co-authored-by: Bartosz Kaszubowski --- website/docusaurus.config.js | 86 +++++++++++++++++--------------- website/src/css/customTheme.scss | 19 ++++++- 2 files changed, 64 insertions(+), 41 deletions(-) diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 36ce3c0d866..ae568c8f9f7 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -214,29 +214,32 @@ module.exports = { style: 'dark', items: [ { - label: 'Guides', - type: 'doc', - docId: 'getting-started', - position: 'right', - }, - { - label: 'Components', - type: 'doc', - docId: 'components-and-apis', + label: 'Development', + type: 'dropdown', position: 'right', - }, - { - label: 'API', - type: 'doc', - docId: 'accessibilityinfo', - position: 'right', - }, - { - label: 'Architecture', - type: 'doc', - docId: 'architecture-overview', - position: 'right', - docsPluginId: 'architecture', + items: [ + { + label: 'Guides', + type: 'doc', + docId: 'getting-started', + }, + { + label: 'Components', + type: 'doc', + docId: 'components-and-apis', + }, + { + label: 'APIs', + type: 'doc', + docId: 'accessibilityinfo', + }, + { + label: 'Architecture', + type: 'doc', + docId: 'architecture-overview', + docsPluginId: 'architecture', + }, + ], }, { type: 'doc', @@ -245,6 +248,11 @@ module.exports = { position: 'right', docsPluginId: 'contributing', }, + { + to: '/showcase', + label: 'Showcase', + position: 'right', + }, { to: '/blog', label: 'Blog', @@ -274,23 +282,23 @@ module.exports = { style: 'dark', links: [ { - title: 'Docs', + title: 'Development', items: [ { - label: 'Getting Started', + label: 'Guides', to: 'docs/getting-started', }, { - label: 'Tutorial', - to: 'docs/tutorial', + label: 'Components', + to: 'docs/components-and-apis', }, { - label: 'Components and APIs', - to: 'docs/components-and-apis', + label: 'APIs', + to: 'docs/accessibilityinfo', }, { - label: 'More Resources', - to: 'docs/more-resources', + label: 'Architecture', + to: 'architecture/overview', }, ], }, @@ -298,20 +306,20 @@ module.exports = { title: 'Community', items: [ { - label: 'The React Native Community', - to: 'help', + label: 'Showcase', + to: 'showcase', }, { - label: "Who's using React Native?", - to: 'showcase', + label: 'Contributing', + to: 'contributing/overview', }, { - label: 'Ask Questions on Stack Overflow', - href: 'https://stackoverflow.com/questions/tagged/react-native', + label: 'The React Native Community', + to: 'help', }, { - label: 'DEV Community', - href: 'https://dev.to/t/reactnative', + label: 'Ask Questions on Stack Overflow', + href: 'https://stackoverflow.com/questions/tagged/react-native', }, ], }, @@ -336,7 +344,7 @@ module.exports = { title: 'More', items: [ { - label: 'React', + label: 'ReactJS', href: 'https://reactjs.org/', }, { diff --git a/website/src/css/customTheme.scss b/website/src/css/customTheme.scss index 432346de123..33451794f50 100644 --- a/website/src/css/customTheme.scss +++ b/website/src/css/customTheme.scss @@ -596,7 +596,7 @@ a[class*="tagRegular"] { user-select: none; } - &.dropdown { + &.dropdown:not(.dropdown--right) { a { font-weight: 400; font-size: 14px; @@ -607,6 +607,18 @@ a[class*="tagRegular"] { left: 0; } } + + &.dropdown--right { + .dropdown__menu { + min-width: 168px; + } + } + } + + .dropdown > .navbar__link:after { + margin-left: 8px; + top: 1px; + opacity: 0.75; } .navbar__logo { @@ -887,7 +899,6 @@ aside[class^="theme-doc-sidebar-container"] { .menu__link--sublist { font-size: 15px; - font-weight: 600; padding: 4px 12px !important; color: var(--light); @@ -897,6 +908,10 @@ aside[class^="theme-doc-sidebar-container"] { } } + .menu__link--sublist-caret { + font-size: 17px; + } + .menu__list { .menu__link { line-height: 20px; From 4e386d6a794568dd6de0a8fc143db6bc34d24ec9 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Wed, 21 Sep 2022 11:41:31 +0100 Subject: [PATCH 32/88] Update docs with AGP 7.3.x setup (#3333) --- docs/new-architecture-app-intro.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/new-architecture-app-intro.md b/docs/new-architecture-app-intro.md index 14bf8772a3b..a8699f6a995 100644 --- a/docs/new-architecture-app-intro.md +++ b/docs/new-architecture-app-intro.md @@ -143,7 +143,7 @@ RCT_NEW_ARCH_ENABLED=1 pod install Using the New Architecture on Android has some prerequisites that you need to meet: 1. Using Gradle version >= 7.x -2. Using Android Gradle Plugin >= 7.x (i.e. the `com.android.tools.build:gradle` dependency) +2. Using Android Gradle Plugin >= 7.3.x (i.e. the `com.android.tools.build:gradle` dependency) If you updated to React Native 0.68+, you already meet those prerequisites. If you don't meet them, consider updating those dependencies first. @@ -266,8 +266,6 @@ android { afterEvaluate { preBuild.dependsOn(packageReactNdkLibs) - configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild) - configureCMakeDebug.dependsOn(preDebugBuild) } packagingOptions { From b5f5b5a31ce666a85fb6383db0b33e17c12e7fcf Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Wed, 21 Sep 2022 08:23:41 -0300 Subject: [PATCH 33/88] Update colors docs regarding expanded support for CSS Colors (#3306) --- docs/colors.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/colors.md b/docs/colors.md index b396bfbfb38..835f8a897cf 100644 --- a/docs/colors.md +++ b/docs/colors.md @@ -26,14 +26,27 @@ React Native supports `rgb()` and `rgba()` in both hexadecimal and functional no - `'#f0ff'` (#rgba) - `'#ff00ff00'` (#rrggbbaa) - `'rgb(255, 0, 255)'` +- `'rgb(255 0 255)'` - `'rgba(255, 0, 255, 1.0)'` +- `'rgba(255 0 255 / 1.0)'` ### Hue Saturation Lightness (HSL) React Native supports `hsl()` and `hsla()` in functional notation: - `'hsl(360, 100%, 100%)'` +- `'hsl(360 100% 100%)'` - `'hsla(360, 100%, 100%, 1.0)'` +- `'hsla(360 100% 100% / 1.0)'` + +### Hue Whiteness Blackness (HWB) + +React Native supports `hwb()` in functional notation: + +- `'hwb(0, 0%, 100%)'` +- `'hwb(360, 100%, 100%)'` +- `'hwb(0 0% 0%)'` +- `'hwb(70 50% 0%)'` ### Color ints From 91ce6bc1535fd5ad5c524150c185cc0d3e3709dd Mon Sep 17 00:00:00 2001 From: Riccardo Date: Wed, 21 Sep 2022 12:52:34 +0100 Subject: [PATCH 34/88] fix: Improve wording for iOS getting started (#3334) --- docs/_getting-started-macos-ios.md | 10 +++++++--- .../backward-compatibility-fabric-components.md | 4 +++- .../backward-compatibility-turbomodules.md | 4 +++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/_getting-started-macos-ios.md b/docs/_getting-started-macos-ios.md index 840b38b5803..7359e734983 100644 --- a/docs/_getting-started-macos-ios.md +++ b/docs/_getting-started-macos-ios.md @@ -21,6 +21,8 @@ If you have already installed Node on your system, make sure it is Node 14 or ne ### Ruby +[Ruby](https://www.ruby-lang.org/en/) is a general-purpose programming language. React Native uses in some scripts related to the iOS dependency management. As every programming language, there are different versions of Ruby that have been developed during the years. + React Native uses a `.ruby-version` file to make sure that your version of Ruby is aligned with what is needed. Currently, macOS 12.5.1 is shipped with Ruby 2.6.8, which is **not** what is required by React Native. Our suggestion is to install a Ruby version manager and to install the proper version of Ruby in your system. Some common Ruby version manager are: @@ -38,9 +40,11 @@ ruby --version React Native uses [this version](https://github.com/facebook/react-native/blob/main/template/_ruby-version) of Ruby. You can also find which version your specific project needs in the `.ruby-version` file at root of your RN project. -### Bundler +### Ruby's Bundler + +Ruby uses the concept of **gems** to handle its own dependencies. You can think of a gem as a package in NPM, a formula in Homebrew or a single pod in Cocoapods. -[Bundler](https://bundler.io/) is a Ruby gem that helps managing the Ruby dependencies of your project. We need Ruby to install Cocoapods and using Bundler will make sure that all the dependencies are aligned and that the project works properly. +Ruby's [Bundler](https://bundler.io/) is a Ruby gem that helps managing the Ruby dependencies of your project. We need Ruby to install Cocoapods and using Bundler will make sure that all the dependencies are aligned and that the project works properly. If you want to learn more about why we need this tool, you can read [this article](https://bundler.io/guides/rationale.html#bundlers-purpose-and-rationale). @@ -62,7 +66,7 @@ To install a simulator, open Xcode > Preferences... and select #### CocoaPods -[CocoaPods](https://cocoapods.org/) is built with Ruby and it will be installable with the default Ruby available on macOS. +[CocoaPods](https://cocoapods.org/) is one of the dependency management system available for iOS. It is built with Ruby and you can install it using the version of Ruby you configured with in the previous steps. For more information, please visit [CocoaPods Getting Started guide](https://guides.cocoapods.org/using/getting-started.html). diff --git a/docs/the-new-architecture/backward-compatibility-fabric-components.md b/docs/the-new-architecture/backward-compatibility-fabric-components.md index 21e65220483..8eb6b47d203 100644 --- a/docs/the-new-architecture/backward-compatibility-fabric-components.md +++ b/docs/the-new-architecture/backward-compatibility-fabric-components.md @@ -24,11 +24,13 @@ Creating a backward compatible Fabric Native Component lets your users continue 1. Uniform the JavaScript API so that your user code won't need changes. :::info + For the sake of this guide we're going to use the following **terminology**: - **Legacy Native Components** - To refer to Components which are running on the old React Native architecture. - **Fabric Native Components** - To refer to Components which have been adapted to work well with the New Native Renderer, Fabric. For brevity you might find them referred as **Fabric Components**. - ::: + +::: diff --git a/docs/the-new-architecture/backward-compatibility-turbomodules.md b/docs/the-new-architecture/backward-compatibility-turbomodules.md index 2cdc68f1608..fbc2e89a063 100644 --- a/docs/the-new-architecture/backward-compatibility-turbomodules.md +++ b/docs/the-new-architecture/backward-compatibility-turbomodules.md @@ -24,11 +24,13 @@ Creating a backward compatible TurboModule lets your users continue to leverage 1. Uniform the JavaScript API so that your user code won't need changes. :::info + For the sake of this guide we're going to use the following **terminology**: - **Legacy Native Modules** - To refer to Modules which are running on the old React Native architecture. - **Turbo Native Modules** - To refer to Modules which have been adapted to work well with the New Native Module System. For brevity you might find them referred as **Turbo Modules**. - ::: + +::: From 875448365a47e9d99a623a54b8e5bc9c6e9b5c37 Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Wed, 21 Sep 2022 09:47:51 -0300 Subject: [PATCH 35/88] Add id prop to Text, TouchableWithoutFeedback and View docs (#3285) --- docs/text.md | 10 ++++++++++ docs/touchablewithoutfeedback.md | 10 ++++++++++ docs/view.md | 12 ++++++++++++ 3 files changed, 32 insertions(+) diff --git a/docs/text.md b/docs/text.md index df60308a436..56d3ce99025 100644 --- a/docs/text.md +++ b/docs/text.md @@ -417,6 +417,16 @@ This can be one of the following values: --- +### `id` + +Used to locate this view from native code. Has precedence over `nativeID` prop. + +| Type | +| ------ | +| string | + +--- + ### `maxFontSizeMultiplier` Specifies the largest possible scale a font can reach when `allowFontScaling` is enabled. Possible values: diff --git a/docs/touchablewithoutfeedback.md b/docs/touchablewithoutfeedback.md index bcfa47f331a..09bb202708b 100644 --- a/docs/touchablewithoutfeedback.md +++ b/docs/touchablewithoutfeedback.md @@ -269,6 +269,16 @@ This defines how far your touch can start away from the button. This is added to | ---------------------- | | [Rect](rect) or number | +### `id` + +Used to locate this view from native code. Has precedence over `nativeID` prop. + +| Type | +| ------ | +| string | + +--- + ### `onBlur` Invoked when the item loses focus. diff --git a/docs/view.md b/docs/view.md index 6be5e2864ac..c4ba9b94ef7 100644 --- a/docs/view.md +++ b/docs/view.md @@ -283,6 +283,18 @@ For example, if a touchable view has a height of 20 the touchable height can be --- +### `id` + +Used to locate this view from native classes. Has precedence over `nativeID` prop. + +> This disables the 'layout-only view removal' optimization for this view! + +| Type | +| ------ | +| string | + +--- + ### `importantForAccessibility`

Controls how view is important for accessibility which is if it fires accessibility events and if it is reported to accessibility services that query the screen. Works for Android only. From 12dc7125d050cc5362a6b75cafebd42dc7578bd3 Mon Sep 17 00:00:00 2001 From: Akshansh Thakur Date: Wed, 21 Sep 2022 23:18:21 +0530 Subject: [PATCH 36/88] Updated button.md to reference Pressable (#3237) --- website/versioned_docs/version-0.69/button.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/versioned_docs/version-0.69/button.md b/website/versioned_docs/version-0.69/button.md index 78f7fcaa637..f3bc2c7f56a 100644 --- a/website/versioned_docs/version-0.69/button.md +++ b/website/versioned_docs/version-0.69/button.md @@ -5,7 +5,7 @@ title: Button A basic button component that should render nicely on any platform. Supports a minimal level of customization. -If this button doesn't look right for your app, you can build your own button using [TouchableOpacity](touchableopacity) or [TouchableWithoutFeedback](touchablewithoutfeedback). For inspiration, look at the [source code for this button component](https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js). Or, take a look at the [wide variety of button components built by the community](https://js.coach/?menu%5Bcollections%5D=React%20Native&page=1&query=button). +If this button doesn't look right for your app, you can build your own button using [Pressable](pressable). For inspiration, look at the [source code for this button component](https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js). Or, take a look at the [wide variety of button components built by the community](https://js.coach/?menu%5Bcollections%5D=React%20Native&page=1&query=button). ```jsx