From c084b5a413a1f2345ae5289b7901eb91773b0279 Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Fri, 9 Sep 2022 21:18:04 +0100 Subject: [PATCH] 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