From 18041b0d36aa7df56388c92e4c6f38aeb03f2683 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Mon, 1 Aug 2022 17:25:32 +0100 Subject: [PATCH] wip: migration guide review (#3200) --- docs/direct-manipulation.md | 4 + docs/intro-react-native-components.md | 12 +- docs/introduction.md | 4 +- docs/more-resources.md | 2 +- docs/native-components-android.md | 3 + docs/native-components-ios.md | 4 + docs/native-modules-android.md | 3 + docs/native-modules-intro.md | 4 + docs/native-modules-ios.md | 4 + docs/native-modules-setup.md | 4 + docs/new-architecture-app-intro.md | 214 ++++++++++++------ docs/new-architecture-app-modules-android.md | 87 ++++--- docs/new-architecture-app-renderer-ios.md | 2 +- docs/new-architecture-appendix.md | 32 ++- docs/new-architecture-intro.md | 4 +- docs/new-architecture-library-android.md | 38 +--- docs/new-architecture-library-intro.md | 95 +++++--- docs/new-architecture-library-ios.md | 66 ++---- docs/react-18-and-react-native.md | 3 + .../_markdown_native_deprecation.mdx | 4 + ...ackward-compatibility-fabric-components.md | 29 +-- .../backward-compatibility-troubleshooting.md | 6 - .../backward-compatibility-turbomodules.md | 29 +-- .../backward-compatibility.md | 10 +- docs/the-new-architecture/landing-page.md | 8 +- docs/the-new-architecture/pillars-codegen.md | 6 +- .../pillars-fabric-components.md | 81 +------ .../pillars-turbomodule.md | 119 +++------- docs/the-new-architecture/pillars.md | 6 +- docs/the-new-architecture/use-app-template.md | 4 +- docs/the-new-architecture/why.md | 4 + website/sidebars.json | 63 +++--- 32 files changed, 489 insertions(+), 465 deletions(-) create mode 100644 docs/the-new-architecture/_markdown_native_deprecation.mdx delete mode 100644 docs/the-new-architecture/backward-compatibility-troubleshooting.md diff --git a/docs/direct-manipulation.md b/docs/direct-manipulation.md index c336455116c..3a711b81c99 100644 --- a/docs/direct-manipulation.md +++ b/docs/direct-manipulation.md @@ -3,6 +3,10 @@ id: direct-manipulation title: Direct Manipulation --- +import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx' + + + It is sometimes necessary to make changes directly to a component without using state/props to trigger a re-render of the entire subtree. When using React in the browser for example, you sometimes need to directly modify a DOM node, and the same is true for views in mobile apps. `setNativeProps` is the React Native equivalent to setting properties directly on a DOM node. :::caution diff --git a/docs/intro-react-native-components.md b/docs/intro-react-native-components.md index 8896c39653c..00d22878aad 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 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!' +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!' --- import ThemedImage from '@theme/ThemedImage'; @@ -17,13 +17,13 @@ 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.
-## Native Components +## 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.** +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. -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 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 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. +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. ## Core Components diff --git a/docs/introduction.md b/docs/introduction.md index f77b91adf9b..b57e6da77ae 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, Native 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, Fabric 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: [Native 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: [Fabric Components](the-new-architecture/pillars-fabric-components). diff --git a/docs/more-resources.md b/docs/more-resources.md index 4dee1a6f333..7e061a9ccb4 100644 --- a/docs/more-resources.md +++ b/docs/more-resources.md @@ -34,7 +34,7 @@ We recommend using the [VS Code](https://code.visualstudio.com/) code editor and Try out apps from the [Showcase](https://reactnative.dev/showcase) to see what React Native is capable of! Looking for something more hands on? Check out this [set of example apps on GitHub](https://github.com/ReactNativeNews/React-Native-Apps). You can look at their source code—try running one on a simulator or device. -## Find, make, and share your own Native Components and Modules +## Find, make, and share your own Native Components and TurboModules React Native has a community of thousands of developers like you making content, tools, tutorials—and Native Components! diff --git a/docs/native-components-android.md b/docs/native-components-android.md index fb275ff3cd4..8404e4a76af 100644 --- a/docs/native-components-android.md +++ b/docs/native-components-android.md @@ -4,6 +4,9 @@ title: Android Native UI Components --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; +import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx' + + There are tons of native UI widgets out there ready to be used in the latest apps - some of them are part of the platform, others are available as third-party libraries, and still more might be in use in your very own portfolio. React Native has several of the most critical platform components already wrapped, like `ScrollView` and `TextInput`, but not all of them, and certainly not ones you might have written yourself for a previous app. Fortunately, we can wrap up these existing components for seamless integration with your React Native application. diff --git a/docs/native-components-ios.md b/docs/native-components-ios.md index eea45ed1db2..bba1b3559f6 100644 --- a/docs/native-components-ios.md +++ b/docs/native-components-ios.md @@ -3,6 +3,10 @@ id: native-components-ios title: iOS Native UI Components --- +import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx' + + + There are tons of native UI widgets out there ready to be used in the latest apps - some of them are part of the platform, others are available as third-party libraries, and still more might be in use in your very own portfolio. React Native has several of the most critical platform components already wrapped, like `ScrollView` and `TextInput`, but not all of them, and certainly not ones you might have written yourself for a previous app. Fortunately, we can wrap up these existing components for seamless integration with your React Native application. Like the native module guide, this too is a more advanced guide that assumes you are somewhat familiar with iOS programming. This guide will show you how to build a native UI component, walking you through the implementation of a subset of the existing `MapView` component available in the core React Native library. diff --git a/docs/native-modules-android.md b/docs/native-modules-android.md index 2ad60b60c4a..df5066d7e2c 100644 --- a/docs/native-modules-android.md +++ b/docs/native-modules-android.md @@ -3,8 +3,11 @@ id: native-modules-android title: Android Native Modules --- +import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx' import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; + + Welcome to Native Modules for Android. Please start by reading the [Native Modules Intro](native-modules-intro) for an intro to what native modules are. ## Create a Calendar Native Module diff --git a/docs/native-modules-intro.md b/docs/native-modules-intro.md index 331419956d5..35162726dfa 100644 --- a/docs/native-modules-intro.md +++ b/docs/native-modules-intro.md @@ -3,6 +3,10 @@ id: native-modules-intro title: Native Modules Intro --- +import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx' + + + Sometimes a React Native app needs to access a native platform API that is not available by default in JavaScript, for example the native APIs to access Apple or Google Pay. Maybe you want to reuse some existing Objective-C, Swift, Java or C++ libraries without having to reimplement it in JavaScript, or write some high performance, multi-threaded code for things like image processing. The NativeModule system exposes instances of Java/Objective-C/C++ (native) classes to JavaScript (JS) as JS objects, thereby allowing you to execute arbitrary native code from within JS. While we don't expect this feature to be part of the usual development process, it is essential that it exists. If React Native doesn't export a native API that your JS app needs you should be able to export it yourself! diff --git a/docs/native-modules-ios.md b/docs/native-modules-ios.md index ae27042c3eb..433acc37cd0 100644 --- a/docs/native-modules-ios.md +++ b/docs/native-modules-ios.md @@ -3,6 +3,10 @@ id: native-modules-ios title: iOS Native Modules --- +import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx' + + + Welcome to Native Modules for iOS. Please start by reading the [Native Modules Intro](native-modules-intro) for an intro to what native modules are. ## Create a Calendar Native Module diff --git a/docs/native-modules-setup.md b/docs/native-modules-setup.md index 75b67a41fd4..42b877394c0 100644 --- a/docs/native-modules-setup.md +++ b/docs/native-modules-setup.md @@ -3,6 +3,10 @@ id: native-modules-setup title: Native Modules NPM Package Setup --- +import NativeDeprecated from './the-new-architecture/\_markdown_native_deprecation.mdx' + + + Native modules are usually distributed as npm packages, except that on top of the usual JavaScript they will include some native code per platform. To understand more about npm packages you may find [this guide](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry) useful. To get set up with the basic project structure for a native module we will use the community tool called [create-react-native-library](https://github.com/callstack/react-native-builder-bob). You can go ahead further and dive deep into how that library works, but for our needs we will only execute the basic script: diff --git a/docs/new-architecture-app-intro.md b/docs/new-architecture-app-intro.md index c04a00c7b87..a1055a3b9b6 100644 --- a/docs/new-architecture-app-intro.md +++ b/docs/new-architecture-app-intro.md @@ -7,40 +7,29 @@ import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; -There’s a few prerequisites that should be addressed before the new architecture is enabled in your application. +There’s a few prerequisites that should be addressed before the New Architecture is enabled in your application. -## Use a React Native nightly release +## Use a React Native >= 0.68 release -At this time, you must use a React Native nightly release in order to get access to the most up to date changes. Eventually, we will recommend targeting a minimum stable open source 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 a specific nightly release. As new revisions of this guide are released, the target nightly release may be updated. The specific nightly version that we will be using throughout the rest of this guide is version `0.0.0-20220201-2008-79975d146`. +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. -Before upgrading your app to a specific nightly release, we recommend upgrading your app to the latest open source release. By upgrading to a published open source release first, you will be able to take advantage of tools like the [upgrade helper](https://react-native-community.github.io/upgrade-helper/) to determine what other changes may be required for your project. - -As of this writing, the latest stable release is `0.67.2`. Once you have upgraded your project to this version successfully, you may proceed to targeting the `0.0.0-20220201-2008-79975d146` nightly release. You may target this nightly release the same way you’d target any other version of React Native: +To update to the most recent version of React Native, you can run this command ```bash -yarn add react-native@0.0.0-20220201-2008-79975d146 +yarn add react-native@0.70.0 ``` -## Install react-native-codegen - -Make sure that you're using the latest version of the [`react-native-codegen`](https://www.npmjs.com/package/react-native-codegen) NPM package. At the time of writing it's `0.0.13`. +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-native-codegen +yarn add react@18.0.0 ``` -:::info - -If you see an error like `***TypeError: RNCodegen.generateFromSchemas is not a function.***`, it means that you're using a older version of `react-native-codegen`. -Make sure you don't have an older version installed under the `node_modules/react-native/node_modules` folder. You can remove that or reinstall everything in node_modules to fix the problem. - -::: - ### Android specifics -Using the new architecture on Android has some prerequisites that you need to meet: +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** @@ -49,23 +38,11 @@ Using the new architecture on Android has some prerequisites that you need to me You can update Gradle by running: ```bash -cd android && ./gradlew wrapper --gradle-version 7.3 --distribution-type=all +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. -If you’re set with it, let’s now install the new Gradle plugin which is distributed through a NPM package called [**`react-native-gradle-plugin`**](https://www.npmjs.com/package/react-native-gradle-plugin). You can do so with: - -```bash -yarn add react-native-gradle-plugin -``` - -You can control if you have the package already installed by doing: - -```bash -ls -la node_modules/react-native-gradle-plugin -``` - Now, you can edit your **top level** `settings.gradle` file to include the following line at the end of the file: ```groovy @@ -73,16 +50,40 @@ 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.0.4") + classpath("com.android.tools.build:gradle:7.2.0") // Add those lines classpath("com.facebook.react:react-native-gradle-plugin") @@ -93,35 +94,68 @@ buildscript { Edit your **module-level** **Gradle file** (usually `app/build.gradle[.kts]`) to include the following: -```groovy +```diff +// ... + apply plugin: "com.android.application" -// Add those lines -apply plugin: "com.facebook.react" -// Add those lines as well -react { - reactRoot = rootProject.file("../node_modules/react-native/") - codegenDir = rootProject.file("../node_modules/react-native-codegen/") -} +// ... + +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 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. Let’s edit your **module level** `build.gradle` (the one inside `app/` folder) and change the following line: -```groovy +```diff dependencies { - // Replace this: - implementation "com.facebook.react:react-native:+" // From node_modules - // With this: - implementation project(":ReactAndroid") // From node_modules +- implementation "com.facebook.react:react-native:+" // From node_modules ++ implementation project(":ReactAndroid") // From node_modules ``` ## Use Hermes -Hermes is an open-source JavaScript engine optimized for React Native. 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. +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) in order to enable Hermes in your application. +Please [follow the instructions on the React Native website](hermes) to learn how to enable/disable Hermes. :::caution @@ -129,29 +163,72 @@ Please [follow the instructions on the React Native website](hermes) in order to ::: -## iOS: Enable C++17 language feature support +### Android + +To enable Hermes in Android, open the `android/app/build.gradle` and apply the following changes: + +```diff +project.ext.react = [ +- enableHermes: true, // clean and rebuild if changing ++ enableHermes: true, // clean and rebuild if changing +] +// ... + +} -Your Xcode project settings need to be updated to support C++17 language features. +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 { +``` -**Instructions** +Moreover, you'll need to update the `proguard-rules`, adding the following ones: -1. Select your project in the Project navigator on the left (e.g. MyXcodeApp) -2. Then, make sure your project is selected in the center pane (as opposed to a particular target in your project, e.g. MyXcodeApp under Project, not under Targets). -3. Go to Build Settings -4. Search for C++ Language Dialect or CLANG_CXX_LANGUAGE_STANDARD -5. Make sure **C++17** is selected from the dropdown menu (or enter "c++17" directly into the value box). +``` +-keep class com.facebook.hermes.unicode.** { *; } +-keep class com.facebook.jni.** { *; } +``` -If done correctly, your diff will show the following changes to your project file: +After that, remember to cleanup the project, running -```ruby -CLANG_CXX_LANGUAGE_STANDARD = "c++17" +```sh +cd android +./gradlew clean ``` -:::info +## iOS: Make the project build -Your project should also be configured to support Folly. This should be done automatically once the library dependency is picked up, so no further changes to your project are necessary. +After upgrading the project, there are a few changes you need to apply: -::: +1. Fix an API change in the `AppDelegate.m`. Open this file and apply this change: + +```diff +#if DEBUG +- return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; ++ return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; +#else +``` + +2. Target the proper iOS version. Open the `Podfile` and apply this change: + +```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: + +```sh +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` which is not synced with the repository, if your local setup is different from the Continuous Integration or team one. ## iOS: Use Objective-C++ (`.mm` extension) @@ -201,14 +278,3 @@ You can implement the `jsExecutorFactoryForBridge:` method like this: ); } ``` - -## iOS: Setup Folly - -The previous step will incorporate in your iOS app a dependency called Folly. Folly requires some extra compiler flags to works properly. To set them up, follow these steps: - -1. In the **Project Navigator** (`cmd+1`), select your app project. -1. In the **Targets** section, select the target with the name of your app. -1. Select the **Build Settings** tab -1. Search for **Other C++ Flags** -1. Update the **Debug** configuration, adding following flags: `-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1` -1. Update the **Release** configuration with the following flags: `-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1` diff --git a/docs/new-architecture-app-modules-android.md b/docs/new-architecture-app-modules-android.md index 23a2a129e5a..3bd05c1db17 100644 --- a/docs/new-architecture-app-modules-android.md +++ b/docs/new-architecture-app-modules-android.md @@ -18,7 +18,7 @@ You can mitigate this by following the approach described in [Speeding up your B ::: -The code-gen will output some Java and some C++ code that now we need to build. +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: @@ -37,10 +37,15 @@ android { "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" + "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" + } } } } @@ -87,42 +92,56 @@ Finally, we need to create a Makefile inside the `src/main/jni` folder called `A THIS_DIR := $(call my-dir) include $(REACT_ANDROID_DIR)/Android-prebuilt.mk -include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk + +# 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) -LOCAL_MODULE := myapplication_appmodules - -LOCAL_C_INCLUDES := $(LOCAL_PATH) $(GENERATED_SRC_DIR)/codegen/jni -LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(GENERATED_SRC_DIR)/codegen/jni - -# Please note as one of the library listed is libreact_codegen_samplelibrary -# This name will be generated as libreact_codegen_ -# where is the one you specified in the Gradle configuration -LOCAL_SHARED_LIBRARIES := libjsi \ - libfbjni \ - libglog \ - libfolly_json \ - libyoga \ - libreact_nativemodule_core \ - libturbomodulejsijni \ - librrc_view \ - libreact_render_core \ - libreact_render_graphics \ - libfabricjni \ - libfolly_futures \ - libreact_debug \ - libreact_render_componentregistry \ - libreact_render_debug \ - libruntimeexecutor \ - libreact_codegen_rncore \ - libreact_codegen_samplelibrary - -LOCAL_CFLAGS := \ - -DLOG_TAG=\"ReactNative\" -LOCAL_CFLAGS += -fexceptions -frtti -std=c++17 -Wall + +# 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) ``` diff --git a/docs/new-architecture-app-renderer-ios.md b/docs/new-architecture-app-renderer-ios.md index 089fcaa8001..39f3226f55f 100644 --- a/docs/new-architecture-app-renderer-ios.md +++ b/docs/new-architecture-app-renderer-ios.md @@ -39,7 +39,7 @@ end ## 2. Update your root view -The way 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. +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 diff --git a/docs/new-architecture-appendix.md b/docs/new-architecture-appendix.md index 1d6ef870ba1..56b3301423b 100644 --- a/docs/new-architecture-appendix.md +++ b/docs/new-architecture-appendix.md @@ -85,11 +85,31 @@ 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. Invoking the code-gen during development +## 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: + +| TypeScript Type | Nullable Support? | Android (Java) | iOS | Note | +| ---------------------------------------------- | -------------------------------------------------------- | ------------------------------------ | -------------------------------------------------------------- | ------------------------------------------------------------------------------ | +| `string` | string | null | `String` | `NSString` | | +| `boolean` | boolean | null | `Boolean` | `NSNumber` | | +| `Float`, `Double`, or `Int32` | No | `double` | `NSNumber` | | +| {| foo: string, ... |} | {| foo: string, ...|} | null | | | Object literal. This is recommended over simply using Object, for type safety. | +| `Object` | Object | null | `ReadableMap` | `@{} (untyped dictionary)` | Recommended to use object literal (see above). | +| `Array<*>` | Array<\*> | null | `ReadableArray` | `NSArray` (or `RCTConvertVecToArray` when used inside objects) | | +| `Function` | Function | null | | | | +| `Promise<*>` | Promise<\*> | null | `com.facebook.react.bridge.Promise` | `RCTPromiseResolve` and `RCTPromiseRejectBlock` | | +| Type aliases of the above | Yes | | | | +| Type Unions 'SUCCESS'|'FAIL' | Only as callbacks. | | | Type unions only supported as callbacks. | +| Callbacks: `( ) =>` | Yes | `com.facebook.react.bridge.Callback` | `RCTResponseSenderBlock` | Callback functions are not type checked, and are generalized as Objects. | + +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 > This section contains information specific to v0.66 of React Native. -The code-gen is typically invoked at build time, but you may find it useful to generate your native interface code on demand for troubleshooting. +The Codegen is typically invoked at build time, but you may find it useful to generate your native interface code on demand for troubleshooting. If you wish to invoke the codegen manually, you have two options: @@ -98,7 +118,7 @@ If you wish to invoke the codegen manually, you have two options: ### Invoking a Gradle task directly -You can trigger the code-gen by invoking the following task: +You can trigger the Codegen by invoking the following task: ```bash ./gradlew generateCodegenArtifactsFromSchema --rerun-tasks @@ -140,12 +160,12 @@ node node_modules/react-native/scripts/generate-specs-cli.js \ [--libraryType all(default)|modules|components] ``` -> **NOTE:** The output artifacts of the code-gen are inside the build folder and should not be committed. +> **NOTE:** The output artifacts of the Codegen are inside the build folder and should not be committed. > They should be considered only for reference. ##### Example -The following is a basic example of invoking the code-gen script to generate native iOS interface code for a library that provides native modules. The JavaScript spec sources for this library are located in a `js/` subdirectory, and this library’s native code expects the native interfaces to be available in the `ios` subdirectory. +The following is a basic example of invoking the Codegen script to generate native iOS interface code for a library that provides native modules. The JavaScript spec sources for this library are located in a `js/` subdirectory, and this library’s native code expects the native interfaces to be available in the `ios` subdirectory. ```bash # Generate schema - only needs to be done whenever JS specs change @@ -162,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. -## III. 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 85d4421639d..39e8ef4abc5 100644 --- a/docs/new-architecture-intro.md +++ b/docs/new-architecture-intro.md @@ -1,6 +1,6 @@ --- id: new-architecture-intro -title: Adopting the New Architecture +title: Migrating to the New Architecture --- import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; @@ -28,4 +28,6 @@ The guide is divided into three sections: - Enabling the New Renderer (Fabric) in your App - [Android](new-architecture-app-renderer-android) - [iOS](new-architecture-app-renderer-ios) +- [**React18 and React Native**](react-18-and-react-native) +- [**Troubleshooting**](new-architecture-troubleshooting) - [**Appendix**](new-architecture-appendix) diff --git a/docs/new-architecture-library-android.md b/docs/new-architecture-library-android.md index 6aba69ab895..ccf72a5769e 100644 --- a/docs/new-architecture-library-android.md +++ b/docs/new-architecture-library-android.md @@ -7,41 +7,9 @@ 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) 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), 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. -### 1. Configure Codegen in your Gradle File - -You can now configure Codegen by specifying the following in the module-level `build.gradle` file: - -```groovy -react { - libraryName = "samplelibrary" - codegenJavaPackageName = "com.example.samplelibrary" - root = rootProject.file("..") - jsRootDir = rootProject.file("../js/") - reactNativeDir = rootProject.file("../node_modules/react-native/") - codegenDir = rootProject.file("../node_modules/react-native-codegen/") -} -``` - -:::info - -Please note that this setup requires you to have the React Gradle Plugin configured in the prerequisite step). - -::: - -All the arguments are **optional** and provide **default values**, you might want to customize them to follow your setup. - -- `libraryName`: A string that identifies your library. By default, the codegen will use a library name that is derived from the name of the module with a `Spec` suffix. E.g. for `:example:project` it will be `ExampleProjectSpec`. -- `codegenJavaPackageName`: A string that represents the Java package your code should use. By default this will be `com.facebook.fbreact.specs` but you might want to customize it. -- `root`: Reference to the root of your project. By default is `..` as Gradle is running inside the `./android` folder. -- `reactNativeDir`: Reference to the `react-native` package root. Usually located inside `../node_modules/react-native`. For third-party NPM libraries that are installed in `node_modules`, this will be `../react-native`. -- `jsRootDir`: Reference to the directory that contains the JavaScript specs for this library. By default is `../js/`. -- `codegenDir`: Reference to the `react-native-codegen` root. Usually located inside `../node_modules/react-native-codegen`. - -The generator will write its output inside the **build folder**, specifically inside the `./build/generated/source/codegen` folder. - -## 2. 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**. @@ -116,4 +84,4 @@ public class NativeAwesomeManager extends NativeAwesomeManagerSpec { } ``` -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 access 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 0f6fc905586..e3d3c242868 100644 --- a/docs/new-architecture-library-intro.md +++ b/docs/new-architecture-library-intro.md @@ -3,40 +3,36 @@ id: new-architecture-library-intro title: Prerequisites for Libraries --- -import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; +import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; The following steps will help ensure your modules and components are ready for the New Architecture. -## TurboModules: Define Specs in JavaScript - -Under the TurboModule system, the JavaScript spec will serve as the source of truth for the methods that are provided by each native module. Without the JavaScript spec, it is up to you to ensure your public method signatures are equivalent on Android and iOS. +## Define Specs in JavaScript -As the first step to adopting the new architecture, you will start by creating these specs for your native modules. You can do this, right now, prior to actually migrating your native module library to the new architecture. Your JavaScript spec will be used later on to generate native interface code for all the supported platforms, as a way to enforce uniform APIs across platforms. - -### Writing the JavaScript Spec - -The JavaScript spec 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 us 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 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. :::info - -JavaScript spec files can be written in either [Flow](https://flow.org/) or [TypeScript](https://www.typescriptlang.org/). The Codegen process will automatically choose the correct type parser based on your spec file's extension (`.js` for Flow, `.ts` or `.tsx` for TypeScript). Note that TypeScript support is still in beta—if you come across any bugs or missing features, please [report them](https://github.com/reactwg/react-native-new-architecture/discussions/categories/q-a). - +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. ::: -#### TurboModules +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 -JavaScript spec files **must** be named `Native.js` (for TypeScript use extension `.ts` or `.tsx`) and they export a `TurboModuleRegistry` `Spec` object. The name convention is important because the Codegen process looks for modules whose spec file (either JavaScript of TypeScript) starts with the keyword `Native`. +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`. -The following snippets show a basic spec template, written in [Flow](https://flow.org/) as well as [TypeScript](https://www.typescriptlang.org/). +The following is a basic JavaScript spec template, written using the [Flow](https://flow.org/) syntax as well as [TypeScript](https://www.typescriptlang.org/). - - + + ```ts // @flow @@ -55,7 +51,7 @@ export default (TurboModuleRegistry.get(''): ?Spec); ``` - + ```ts import type { TurboModule } from 'react-native'; @@ -80,8 +76,10 @@ JavaScript spec files **must** be named `NativeComponent.js` ( The following snippet shows a basic JavaScript spec template, written in [Flow](https://flow.org/) as well as [TypeScript](https://www.typescriptlang.org/). - - + + ```ts // @flow strict-local @@ -101,7 +99,7 @@ export default (codegenNativeComponent( ``` - + ```ts import type { ViewProps } from 'ViewPropTypes'; @@ -124,15 +122,16 @@ export default codegenNativeComponent( When using Flow or TypeScript, you will be using [type annotations](https://flow.org/en/docs/types/) to define your spec. Keeping in mind that the goal of defining a JavaScript spec is to ensure the generated native interface code is type safe, the set of supported types will be those that can be mapped one-to-one to a corresponding type on the native platform. - + 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. -> See Appendix [I. Flow Type to Native Type Mapping](./new-architecture-appendix#i-flow-type-to-native-type-mapping). (TypeScript to Native Type Mapping will be added soon.) +> 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). ### 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. @@ -158,9 +157,22 @@ android/settings.gradle:apply from: file("../node_modules/@react-native-communit ... ``` +If you don't, open the `settings.gradle` file and add this line: + +```diff +rootProject.name = ++ apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) +``` + +Then, open your `android/app/build.gradle` file and add this line at the end of the file: + +```kotlin +apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) +``` + ### iOS -On iOS, this generally requires your library to provide a Podspec (see [`react-native-webview`](https://github.com/react-native-community/react-native-webview/blob/master/react-native-webview.podspec) for an example). +On iOS, make sure that your library provides a Podspec (see [`react-native-webview`](https://github.com/react-native-community/react-native-webview/blob/master/react-native-webview.podspec) for an example). :::info @@ -168,11 +180,38 @@ 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 can be configured in the `package.json` file of your Library. Add the following JSON object at the end of it. + +```diff + }, ++ "codegenConfig": { ++ "name": "", ++ "type": "all", ++ "jsSrcsDir": ".", ++ "android": { ++ "javaPackageName": "com.facebook.fbreact.specs" ++ } ++ } +} +``` + +- 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 `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) 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! -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` won’t be compatible with React 18 once we are ready to roll that out. 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). +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). While we know that all deprecations are a hassle, this guide is intended to help people update components as smoothly as possible. Here are the steps you need to take to get your JS codebase ready for Fabric: @@ -428,7 +467,7 @@ Be wary of your assumptions as uncaught subtleties can introduce differences in ### Move the call to `requireNativeComponent` to a separate file -This will prepare for the JS to be ready for the new codegen system for the new architecture. The new file should be named `NativeComponent.js.` +This will prepare for the JS to be ready for the new codegen system for the New Architecture. The new file should be named `NativeComponent.js.` #### Old way diff --git a/docs/new-architecture-library-ios.md b/docs/new-architecture-library-ios.md index aa66a59613f..71e276bed18 100644 --- a/docs/new-architecture-library-ios.md +++ b/docs/new-architecture-library-ios.md @@ -8,11 +8,11 @@ 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 +## 1. Updating your Podspec for the New Architecture -The new architecture makes use of CocoaPods. +The New Architecture makes use of CocoaPods. ### Add Folly and Other Dependencies @@ -21,9 +21,6 @@ We'll need to ensure Folly is configured properly in any projects that consume y Add these to your `Pod::Spec.new` block: ```ruby -# folly_version must match the version used in React Native -# See folly_version in react-native/React/FBReactNativeSpec/FBReactNativeSpec.podspec -folly_version = '2021.06.28.00-v2' 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| @@ -35,9 +32,9 @@ 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 Component s.dependency "React-Codegen" - s.dependency "RCT-Folly", folly_version + s.dependency "RCT-Folly" s.dependency "RCTRequired" s.dependency "RCTTypeSafety" s.dependency "ReactCommon/turbomodule/core" @@ -53,53 +50,28 @@ Currently, the Folly version used here must match the Folly version used by Reac ::: -### Enable codegen in your `package.json` - -At this point, you are now ready to enable code-gen support in your library. In your library’s package.json add the following: +## 2. Extend or implement the code-generated native interfaces -:::info +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. -Please note that this format is subject to change. +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**. -::: - -```json title="package.json" -"codegenConfig": { - "libraries": [ - { - "name": "YourTurboModuleSpec", - "type": "modules", - "jsSrcsDir": "Libraries" - }, - { - "name": "YourComponentName", - "type": "components", - "jsSrcsDir": "Libraries" - } - ] -} +```sh +cd +node node_modules/react_native/scripts/generate-artifacts.js \ + --path / \ + --outputPath \ ``` -There's three arguments that are required: - -- `name`: A name of your library. This will be used to determine import path for your library. -- `jsSrcsDir`: Path to the directory that contains the JavaScript specs for this library. - -These arguments are optional: - -- `type`: Optional. A string that determines which types of artifacts will be generated for your library: “modules” or “components”. If left unspecified, both modules and components artifacts will be generated. - -## 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. +This command will generate the boilerplate code required by iOS in the output path provided as paramenter. -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 code-gen script to generate your library’s native interface code in order to use as reference. 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. +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. ### Conform to the protocols provided by the native interface code -Update your native module or component to ensure it implements/extends the native interface that has been code-generated from your JavaScript specs. +Update your native module or component to ensure it implements/extends the native interface that has been generated from your JavaScript specs. -Following the example set forth in the previous section, your library might import MyAwesomeSpecs.h, extend the relevant native interface, and implement the necessary methods for this interface: +Following the example set forth in the previous section, your library might import `MyAwesomeSpecs.h`, extend the relevant native interface, and implement the necessary methods for this interface: ```objc #import @@ -110,7 +82,7 @@ Following the example set forth in the previous section, your library might impo RCT_EXPORT_METHOD(getString:(NSString *)string callback:(RCTResponseSenderBlock)callback) { - // ... + // Implement this method } - (std::shared_ptr)getTurboModule:(const ObjCTurboModule::InitParams &)params @@ -119,4 +91,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 makes use of the structs provided by the codegen output. diff --git a/docs/react-18-and-react-native.md b/docs/react-18-and-react-native.md index 6fe75cf445e..ed4a5d09eb6 100644 --- a/docs/react-18-and-react-native.md +++ b/docs/react-18-and-react-native.md @@ -4,6 +4,9 @@ title: React 18 & React Native --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; +import NewArchitectureWarning from './\_markdown-new-architecture-warning.mdx'; + + This page describes how to use React 18 with React Native using the React Native's New Architecture. diff --git a/docs/the-new-architecture/_markdown_native_deprecation.mdx b/docs/the-new-architecture/_markdown_native_deprecation.mdx new file mode 100644 index 00000000000..569a078d147 --- /dev/null +++ b/docs/the-new-architecture/_markdown_native_deprecation.mdx @@ -0,0 +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. +::: diff --git a/docs/the-new-architecture/backward-compatibility-fabric-components.md b/docs/the-new-architecture/backward-compatibility-fabric-components.md index 233da8f0764..8226a24730f 100644 --- a/docs/the-new-architecture/backward-compatibility-fabric-components.md +++ b/docs/the-new-architecture/backward-compatibility-fabric-components.md @@ -7,6 +7,9 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; import BetaTS from './\_markdown_beta_ts_support.mdx'; +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). @@ -37,7 +40,7 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_version = '2021.06.28.00-v2' +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| @@ -249,23 +252,23 @@ The final folder structure looks like this: ```sh my-component ├── android -│   ├── build.gradle -│   └── src -│   ├── main -│   │ ├── AndroidManifest.xml -│   │ └── java -│   │ └── com -│   │ └── MyComponent -│   │ ├── MyComponentView.java -│   │ ├── MyComponentViewManagerImpl.java -│   │ └── MyComponentViewPackage.java +│ ├── build.gradle +│ └── src +│ ├── main +│ │ ├── AndroidManifest.xml +│ │ └── java +│ │ └── com +│ │ └── MyComponent +│ │ ├── MyComponentView.java +│ │ ├── MyComponentViewManagerImpl.java +│ │ └── MyComponentViewPackage.java │ ├── newarch │ │ └── java -│   │ └── com +│ │ └── com │ │ └── MyComponentViewManager.java │ └── oldarch │ └── java -│   └── com +│ └── com │ └── MyComponentViewManager.java ├── ios ├── js diff --git a/docs/the-new-architecture/backward-compatibility-troubleshooting.md b/docs/the-new-architecture/backward-compatibility-troubleshooting.md deleted file mode 100644 index d2091da5d91..00000000000 --- a/docs/the-new-architecture/backward-compatibility-troubleshooting.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -id: backward-compatibility-troubleshooting -title: Troubleshooting ---- - -This section contains solutions to common problems that can happen when developing a backward compatible module or component. diff --git a/docs/the-new-architecture/backward-compatibility-turbomodules.md b/docs/the-new-architecture/backward-compatibility-turbomodules.md index 3f4caa7b15c..42d8a1cbc87 100644 --- a/docs/the-new-architecture/backward-compatibility-turbomodules.md +++ b/docs/the-new-architecture/backward-compatibility-turbomodules.md @@ -7,6 +7,9 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; import BetaTS from './\_markdown_beta_ts_support.mdx'; +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). @@ -37,7 +40,7 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_version = '2021.06.28.00-v2' +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| @@ -88,7 +91,7 @@ Therefore, we can leverage this environment variable in the `podspec` to exclude ```diff + if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then - # The following lines are required by the New Architecture. + # 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" @@ -197,22 +200,22 @@ The final folder structure looks like this: ```sh my-module ├── android -│   ├── build.gradle -│   └── src -│   ├── main -│   │ ├── AndroidManifest.xml -│   │ └── java -│   │ └── com -│   │ └── MyModule -│   │ ├── MyModuleImpl.java -│   │ └── MyModulePackage.java +│ ├── build.gradle +│ └── src +│ ├── main +│ │ ├── AndroidManifest.xml +│ │ └── java +│ │ └── com +│ │ └── MyModule +│ │ ├── MyModuleImpl.java +│ │ └── MyModulePackage.java │ ├── newarch │ │ └── java -│   │ └── com +│ │ └── com │ │ └── MyModule.java │ └── oldarch │ └── java -│   └── com +│ └── com │ └── MyModule.java ├── ios ├── js diff --git a/docs/the-new-architecture/backward-compatibility.md b/docs/the-new-architecture/backward-compatibility.md index 91588284ca8..3e0e1f01cf4 100644 --- a/docs/the-new-architecture/backward-compatibility.md +++ b/docs/the-new-architecture/backward-compatibility.md @@ -3,13 +3,17 @@ id: backward-compatibility title: What Backward Compatibility Is --- -Creating a backward compatible module is important to provide a library that works in both the **Old Architecture** and the **New Architecture**. Not all the users of your library will immediately jump on the new architecture ship: it is a good thing that they will be able to use your library even if they are still using the old architecture. +import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; -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. + + +Creating a backward compatible module is important to provide a library that works in both the **Old Architecture** and the **New Architecture**. Not all the users of your library will immediately jump on the New Architecture ship: it is a good thing that they will be able to use your library even if they are still using the old architecture. + +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: -1. **Update the installation configuration** to avoid downloading dependencies that are not needed by the Old Architecture. +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. 1. **Configure the specs to load the proper implementation**, so that the JavaScript layer leverages the New Architecture whan it is available. diff --git a/docs/the-new-architecture/landing-page.md b/docs/the-new-architecture/landing-page.md index 1471c2cf416..403a1dee659 100644 --- a/docs/the-new-architecture/landing-page.md +++ b/docs/the-new-architecture/landing-page.md @@ -3,13 +3,17 @@ id: landing-page title: Introduction --- -Starting in 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. +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. 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 +- [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 ec6532e0e6c..f7510cff97f 100644 --- a/docs/the-new-architecture/pillars-codegen.md +++ b/docs/the-new-architecture/pillars-codegen.md @@ -3,6 +3,10 @@ id: pillars-codegen title: Codegen --- +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. @@ -138,7 +142,7 @@ Android `Codegen` relies on a Gradle task to generate the required code. First, After that, you can navigate into the `SampleApp/android` folder and run: ```sh -./gradlew generateCodegenArtifactsFromSchema --rerun-tasks +./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. diff --git a/docs/the-new-architecture/pillars-fabric-components.md b/docs/the-new-architecture/pillars-fabric-components.md index f04f75d9387..03d7afc3082 100644 --- a/docs/the-new-architecture/pillars-fabric-components.md +++ b/docs/the-new-architecture/pillars-fabric-components.md @@ -3,6 +3,10 @@ id: pillars-fabric-components title: Fabric Components --- +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**: @@ -13,7 +17,7 @@ A Fabric Component is a UI component rendered on the screen using the [Fabric Re 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 Component, step-by-step. +The following section guides you through the creation of a Fabric Component, step-by-step, targeting React Native 0.70.0. :::caution Fabric Components only works with the **New Architecture** enabled. @@ -161,13 +165,9 @@ The shared configuration is a `package.json` file that will be used by yarn when "react-native": "*" }, "codegenConfig": { - "libraries": [ - { - "name": "RTNCenteredTextSpecs", - "type": "components", - "jsSrcsDir": "js" - } - ] + "name": "RTNCenteredTextSpecs", + "type": "components", + "jsSrcsDir": "js" } } ``` @@ -193,7 +193,7 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_version = '2021.06.28.00-v2' +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| @@ -296,21 +296,8 @@ repositories { dependencies { implementation 'com.facebook.react:react-native:+' } - -react { - jsRootDir = file("../js/") - libraryName = "RTNCenteredText" - codegenJavaPackageName = "com.RTNCenteredText" -} ``` -Of interest in the `build.gradle` file: - -- The `react` block configures the CodeGen process. For Android, we need to specify: - - the `jsRootDir`, which contains the relative path to the JavaScript specs - - the `libraryName` we will use to link the library in the app. - - the `codegenJavaPackageName` which corresponds to the name of the Java package we will use for the code generated by **CodeGen**. - #### The `AndroidManifest.xml` Second, create an `android/src/main` folder. Inside that folder, create a `AndroidManifest.xml` file, with the following code: @@ -836,59 +823,11 @@ You may have to run `bundle install` once before you can use `RCT_NEW_ARCH_ENABL ### Android -Android configuration requires more steps to use your new Component. First, you need to enable the **New Architecture**. +Android configuration requires to enable the **New Architecture**. 1. Open the `android/gradle.properties` file 2. Scroll down to the end of the file and switch the `newArchEnabled` property from `false` to `true`. -Then, you need to instruct the `Android.mk` file that it needs to build also the new library. -This can be with these steps: - -1. Open the `android/app/src/main/jni/Android.mk` file -1. Add this line to include the library at the beginning of the file: - - ```diff - include $(REACT_ANDROID_DIR)/Android-prebuilt.mk - - # 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 - - +include $(NODE_MODULES_DIR)/rtn-centered-text/android/build/generated/source/codegen/jni/Android.mk - include $(CLEAR_VARS) - ``` - -1. In the same file, scroll down until you find a list of `libreact` libraries. There, you have to add the the library that has been generated. To do so, you need to add this line: - ```diff - libreact_codegen_rncore \ - +libreact_codegen_RTNCenteredText \ - libreact_debug \ - ``` - -:::note -The name of the library is `libreact_codegen_` where `` is the value that has been set in the config. -Also, this step won't be necessary anymore as soon as a version of React Native that supports autolinking for Android is released. -::: - -Finally, you need to configure the Fabric component registry to load the Fabric Component at runtime. - -1. Open the `MyApp/android/app/src/main/jni/MainComponentsRegistry.cpp` -1. Add the following include: - - ```c++ - #include - ``` - -1. Update the `sharedProviderRegistry` with this line: - - ```diff - auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); - - +providerRegistry->add(concreteComponentDescriptorProvider()); - - // Custom Fabric Components go here. You can register custom - ``` - ### JavaScript Finally, you can read the Component in your JavaScript application. diff --git a/docs/the-new-architecture/pillars-turbomodule.md b/docs/the-new-architecture/pillars-turbomodule.md index 07155eec315..9ccd7a9820f 100644 --- a/docs/the-new-architecture/pillars-turbomodule.md +++ b/docs/the-new-architecture/pillars-turbomodule.md @@ -4,6 +4,9 @@ title: TurboModules --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; +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. @@ -147,13 +150,12 @@ The shared configuration is a `package.json` file that will be used by yarn when "react-native": "*" }, "codegenConfig": { - "libraries": [ - { - "name": "RTNCalculatorSpec", - "type": "modules", - "jsSrcsDir": "js" - } - ] + "name": "RTNCalculatorSpec", + "type": "modules", + "jsSrcsDir": "js", + "android": { + "javaPackageName": "com.calculator" + } } } ``` @@ -167,6 +169,7 @@ Finally, the **Codegen** configuration is specified by the `codegenConfig` field - `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`. - `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 @@ -179,7 +182,7 @@ require "json" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_version = '2021.06.28.00-v2' +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| @@ -275,21 +278,8 @@ repositories { dependencies { implementation 'com.facebook.react:react-native:+' } - -react { - jsRootDir = file("../js/") - libraryName = "RTNCalculator" - codegenJavaPackageName = "com.RTNCalculator" -} ``` -Of interest in the `build.gradle` file: - -- The `react` block configures the Codegen process. For Android, we need to specify: - - the `jsRootDir`, which contains the relative path to the JavaScript specs - - the `libraryName` we will use to link the library in the app. - - the `codegenJavaPackageName` which corresponds to the name of the Java package we will use for the code generated by **Codegen**. - #### The `AndroidManifest.xml` Second, create an `android/src/main` folder. Inside that folder, create a `AndroidManifest.xml` file, with the following code: @@ -379,13 +369,13 @@ generated └── generated └── ios ├── FBReactNativeSpec - │  ├── FBReactNativeSpec-generated.mm - │  └── FBReactNativeSpec.h + │ ├── FBReactNativeSpec-generated.mm + │ └── FBReactNativeSpec.h ├── RCTThirdPartyFabricComponentsProvider.h ├── RCTThirdPartyFabricComponentsProvider.mm ├── RTNCalculatorSpec - │  ├── RTNCalculatorSpec-generated.mm - │  └── RTNCalculatorSpec.h + │ ├── RTNCalculatorSpec-generated.mm + │ └── RTNCalculatorSpec.h └── react └── renderer └── components @@ -502,24 +492,24 @@ The generated code is stored in the `MyApp/node_modules/rtn-calculator/android/b ```title="Android generated code" codegen ├── java -│  └── com -│  └── RTNCalculator -│  └── NativeCalculatorSpec.java +│ └── com +│ └── RTNCalculator +│ └── NativeCalculatorSpec.java ├── jni -│  ├── Android.mk -│  ├── RTNCalculator-generated.cpp -│  ├── RTNCalculator.h -│  └── react -│  └── renderer -│  └── components -│  └── RTNCalculator -│  ├── ComponentDescriptors.h -│  ├── EventEmitters.cpp -│  ├── EventEmitters.h -│  ├── Props.cpp -│  ├── Props.h -│  ├── ShadowNodes.cpp -│  └── ShadowNodes.h +│ ├── Android.mk +│ ├── RTNCalculator-generated.cpp +│ ├── RTNCalculator.h +│ └── react +│ └── renderer +│ └── components +│ └── RTNCalculator +│ ├── ComponentDescriptors.h +│ ├── EventEmitters.cpp +│ ├── EventEmitters.h +│ ├── Props.cpp +│ ├── Props.h +│ ├── ShadowNodes.cpp +│ └── ShadowNodes.h └── schema.json ``` @@ -669,54 +659,11 @@ You may have to run `bundle install` once before you can use `RCT_NEW_ARCH_ENABL ### Android -Android configuration requires slightly more steps in order to be able to use your new TurboModule. - -First, to enable the **New Architecture**: +Android configuration requires to enable the **New Architecture**: 1. Open the `android/gradle.properties` file 2. Scroll down to the end of the file and switch the `newArchEnabled` property from `false` to `true`. -Then, to manually link your new TurboModule: - -1. Open the `NewArchitecture/android/app/src/main/jni/Android.mk` file and update the file as it follows: - ```diff - # 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 - + - + include $(NODE_MODULES_DIR)/rtn-calculator/android/build/generated/source/codegen/jni/Android.mk - include $(CLEAR_VARS) - ``` -1. In the same file above, go to the `LOCAL_SHARED_LIBRARIES` setting and add the following line: - ```diff - libreact_codegen_rncore \ - + libreact_codegen_RTNCalculator \ - libreact_debug \ - ``` -1. Open the `NewArchitecture/android/app/src/main/jni/MainApplicationModuleProvider.cpp` file and update the file as it follows: - - 1. Add the import for the calculator: - ```diff - #include - + #include - ``` - 1. Add the following check in the `MainApplicationModuleProvider` constructor: - - ```diff - // auto module = samplelibrary_ModuleProvider(moduleName, params); - // if (module != nullptr) { - // return module; - // } - - + auto module = RTNCalculator_ModuleProvider(moduleName, params); - + if (module != nullptr) { - + return module; - + } - - return rncore_ModuleProvider(moduleName, params); - } - ``` - ### JavaScript Now you can use your TurboModule calculator in your app! diff --git a/docs/the-new-architecture/pillars.md b/docs/the-new-architecture/pillars.md index 25ab983e22e..8a0841c1eff 100644 --- a/docs/the-new-architecture/pillars.md +++ b/docs/the-new-architecture/pillars.md @@ -3,6 +3,10 @@ id: pillars title: What Compose the New Architecture --- +import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; + + + The New Architecture is composed mainly by two pillars: - [TurboModules](pillars-turbomodules) @@ -19,7 +23,7 @@ The next sections contain an high-level overview of the pillars, together with t 1. Implement the Native code. 1. Integrate the code in the app. -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. +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. diff --git a/docs/the-new-architecture/use-app-template.md b/docs/the-new-architecture/use-app-template.md index 56fe73d8267..ca4ed3d3dad 100644 --- a/docs/the-new-architecture/use-app-template.md +++ b/docs/the-new-architecture/use-app-template.md @@ -4,8 +4,10 @@ title: Creating a New Architecture App --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import constants from '@site/core/TabsConstants'; - import RemoveGlobalCLI from '.././\_remove-global-cli.md'; +import NewArchitectureWarning from '../\_markdown-new-architecture-warning.mdx'; + + This page will help you create a new React Native app that uses the New Architecture. diff --git a/docs/the-new-architecture/why.md b/docs/the-new-architecture/why.md index fe981627ded..c2b9065f593 100644 --- a/docs/the-new-architecture/why.md +++ b/docs/the-new-architecture/why.md @@ -3,6 +3,10 @@ id: why 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. This is not a technical deep dive: for further technical information, refer to the [Architecture](/architecture/overview) tab of the website. diff --git a/website/sidebars.json b/website/sidebars.json index 88533332f39..d7c018d1bc8 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -105,46 +105,39 @@ "items": [ "the-new-architecture/backward-compatibility", "the-new-architecture/backward-compatibility-turbomodules", - "the-new-architecture/backward-compatibility-fabric-components", - "the-new-architecture/backward-compatibility-troubleshooting" + "the-new-architecture/backward-compatibility-fabric-components" + ] + } + ], + "Migrati to the New Architecture": [ + "new-architecture-intro", + { + "type": "category", + "label": "Supporting in your Library", + "collapsible": false, + "collapsed": false, + "items": [ + "new-architecture-library-intro", + "new-architecture-library-android", + "new-architecture-library-ios" ] }, { "type": "category", - "label": "Migration", + "label": "Supporting in your App", "collapsible": false, "collapsed": false, "items": [ - "new-architecture-intro", - { - "type": "category", - "label": "Supporting in your Library", - "collapsible": false, - "collapsed": false, - "items": [ - "new-architecture-library-intro", - "new-architecture-library-android", - "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-modules-ios", - "new-architecture-app-renderer-android", - "new-architecture-app-renderer-ios" - ] - }, - "react-18-and-react-native", - "new-architecture-troubleshooting", - "new-architecture-appendix" + "new-architecture-app-intro", + "new-architecture-app-modules-android", + "new-architecture-app-modules-ios", + "new-architecture-app-renderer-android", + "new-architecture-app-renderer-ios" ] - } + }, + "react-18-and-react-native", + "new-architecture-troubleshooting", + "new-architecture-appendix" ], "Android and iOS guides": [ { @@ -152,7 +145,11 @@ "label": "Android", "collapsible": false, "collapsed": false, - "items": ["headless-js-android", "signed-apk-android", "communication-android"] + "items": [ + "headless-js-android", + "signed-apk-android", + "communication-android" + ] }, { "type": "category",