diff --git a/README.md b/README.md index b1146205..e7581e99 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ See the below table to find out which version of the template to use. | React Native | Template | | ------------ | -------- | +| 0.69 | 6.11.\* | | 0.68 | 6.10.\* | | 0.67 | 6.9.\* | | 0.66 | 6.8.\* | diff --git a/template/Gemfile b/template/Gemfile index 2c3edcf4..5efda89f 100644 --- a/template/Gemfile +++ b/template/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version -ruby '2.7.4' +ruby '2.7.5' gem 'cocoapods', '~> 1.11', '>= 1.11.2' diff --git a/template/_gitignore b/template/_gitignore index 81570d99..344481b2 100644 --- a/template/_gitignore +++ b/template/_gitignore @@ -20,6 +20,7 @@ DerivedData *.hmap *.ipa *.xcuserstate +ios/.xcode.env.local # Android/IntelliJ # @@ -49,9 +50,10 @@ buck-out/ # For more information about the recommended setup visit: # https://docs.fastlane.tools/best-practices/source-control/ -*/fastlane/report.xml -*/fastlane/Preview.html -*/fastlane/screenshots +**/fastlane/report.xml +**/fastlane/Preview.html +**/fastlane/screenshots +**/fastlane/test_output # Bundle artifact *.jsbundle diff --git a/template/android/app/build.gradle b/template/android/app/build.gradle index 9a7db522..3081a1f2 100644 --- a/template/android/app/build.gradle +++ b/template/android/app/build.gradle @@ -1,7 +1,6 @@ apply plugin: "com.android.application" import com.android.build.OutputFile -import org.apache.tools.ant.taskdefs.condition.Os /** * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets @@ -152,17 +151,13 @@ 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" // Make sure this target name is the same you specify inside the // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable. targets "helloworld_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" - } } } if (!enableSeparateBuildPerCPUArchitecture) { @@ -282,9 +277,10 @@ dependencies { } if (enableHermes) { - def hermesPath = "../../node_modules/hermes-engine/android/"; - debugImplementation files(hermesPath + "hermes-debug.aar") - releaseImplementation files(hermesPath + "hermes-release.aar") + //noinspection GradleDynamicVersion + implementation("com.facebook.react:hermes-engine:+") { // From node_modules + exclude group:'com.facebook.fbjni' + } } else { implementation jscFlavor } @@ -297,7 +293,11 @@ if (isNewArchitectureEnabled()) { 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") + .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") } } } diff --git a/template/android/app/src/main/java/com/helloworld/MainActivity.java b/template/android/app/src/main/java/com/helloworld/MainActivity.java index 24f41285..405d80a8 100644 --- a/template/android/app/src/main/java/com/helloworld/MainActivity.java +++ b/template/android/app/src/main/java/com/helloworld/MainActivity.java @@ -17,7 +17,8 @@ protected String getMainComponentName() { /** * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and - * you can specify the rendered you wish to use (Fabric or the older renderer). + * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer + * (Paper). */ @Override protected ReactActivityDelegate createReactActivityDelegate() { @@ -36,5 +37,12 @@ protected ReactRootView createRootView() { reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED); return reactRootView; } + + @Override + protected boolean isConcurrentRootEnabled() { + // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18). + // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html + return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; + } } } diff --git a/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java b/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java index f555e364..55473c3f 100644 --- a/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java +++ b/template/android/app/src/main/java/com/helloworld/newarchitecture/MainApplicationReactNativeHost.java @@ -16,8 +16,8 @@ import com.facebook.react.bridge.UIManager; import com.facebook.react.fabric.ComponentFactory; import com.facebook.react.fabric.CoreComponentsRegistry; -import com.facebook.react.fabric.EmptyReactNativeConfig; import com.facebook.react.fabric.FabricJSIModuleProvider; +import com.facebook.react.fabric.ReactNativeConfig; import com.facebook.react.uimanager.ViewManagerRegistry; import com.helloworld.BuildConfig; import com.helloworld.newarchitecture.components.MainComponentsRegistry; @@ -105,7 +105,7 @@ public JSIModuleProvider getJSIModuleProvider() { return new FabricJSIModuleProvider( reactApplicationContext, componentFactory, - new EmptyReactNativeConfig(), + ReactNativeConfig.DEFAULT_CONFIG, viewManagerRegistry); } }); diff --git a/template/android/app/src/main/jni/Android.mk b/template/android/app/src/main/jni/Android.mk index 0ae63667..cda13912 100644 --- a/template/android/app/src/main/jni/Android.mk +++ b/template/android/app/src/main/jni/Android.mk @@ -17,7 +17,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) # 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 +# 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 @@ -28,8 +28,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) LOCAL_SHARED_LIBRARIES := \ libfabricjni \ libfbjni \ - libfolly_futures \ - libfolly_json \ + libfolly_runtime \ libglog \ libjsi \ libreact_codegen_rncore \ diff --git a/template/android/build.gradle b/template/android/build.gradle index 5dfc68a6..c9bc539d 100644 --- a/template/android/build.gradle +++ b/template/android/build.gradle @@ -22,9 +22,9 @@ buildscript { mavenCentral() } dependencies { - classpath("com.android.tools.build:gradle:7.0.4") + classpath("com.android.tools.build:gradle:7.1.1") classpath("com.facebook.react:react-native-gradle-plugin") - classpath("de.undercouch:gradle-download-task:4.1.2") + classpath("de.undercouch:gradle-download-task:5.0.1") // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/template/android/settings.gradle b/template/android/settings.gradle index 2f93b711..bd838b9c 100644 --- a/template/android/settings.gradle +++ b/template/android/settings.gradle @@ -6,4 +6,6 @@ includeBuild('../node_modules/react-native-gradle-plugin') if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { 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') } diff --git a/template/ios/HelloWorld.xcodeproj/project.pbxproj b/template/ios/HelloWorld.xcodeproj/project.pbxproj index 7dfdffdd..70234ff0 100644 --- a/template/ios/HelloWorld.xcodeproj/project.pbxproj +++ b/template/ios/HelloWorld.xcodeproj/project.pbxproj @@ -256,13 +256,15 @@ files = ( ); inputPaths = ( + "$(SRCROOT)/.xcode.env.local", + "$(SRCROOT)/.xcode.env", ); name = "Bundle React Native code and images"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n"; + shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; @@ -436,7 +438,7 @@ "$(inherited)", ); INFOPLIST_FILE = HelloWorldTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -460,7 +462,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; INFOPLIST_FILE = HelloWorldTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -576,7 +578,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", @@ -640,7 +642,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.4; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", diff --git a/template/ios/HelloWorld/AppDelegate.mm b/template/ios/HelloWorld/AppDelegate.mm index cef8d202..28475b9c 100644 --- a/template/ios/HelloWorld/AppDelegate.mm +++ b/template/ios/HelloWorld/AppDelegate.mm @@ -16,6 +16,8 @@ #import +static NSString *const kRNConcurrentRoot = @"concurrentRoot"; + @interface AppDelegate () { RCTTurboModuleManager *_turboModuleManager; RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; @@ -41,7 +43,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; #endif - UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"HelloWorld", nil); + NSDictionary *initProps = [self prepareInitialProps]; + UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"HelloWorld", initProps); if (@available(iOS 13.0, *)) { rootView.backgroundColor = [UIColor systemBackgroundColor]; @@ -57,6 +60,28 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( return YES; } +/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off. +/// +/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html +/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture). +/// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`. +- (BOOL)concurrentRootEnabled +{ + // Switch this bool to turn on and off the concurrent root + return true; +} + +- (NSDictionary *)prepareInitialProps +{ + NSMutableDictionary *initProps = [NSMutableDictionary new]; + +#ifdef RCT_NEW_ARCH_ENABLED + initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]); +#endif + + return initProps; +} + - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG diff --git a/template/ios/Podfile b/template/ios/Podfile index 01506faf..06a02f93 100644 --- a/template/ios/Podfile +++ b/template/ios/Podfile @@ -1,7 +1,7 @@ require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' -platform :ios, '11.0' +platform :ios, '12.4' install! 'cocoapods', :deterministic_uuids => false target 'HelloWorld' do diff --git a/template/ios/_xcode.env b/template/ios/_xcode.env new file mode 100644 index 00000000..3d5782c7 --- /dev/null +++ b/template/ios/_xcode.env @@ -0,0 +1,11 @@ +# This `.xcode.env` file is versioned and is used to source the environment +# used when running script phases inside Xcode. +# To customize your local environment, you can create an `.xcode.env.local` +# file that is not versioned. + +# NODE_BINARY variable contains the PATH to the node executable. +# +# Customize the NODE_BINARY variable here. +# For example, to use nvm with brew, add the following line +# . "$(brew --prefix nvm)/nvm.sh" --no-use +export NODE_BINARY=$(command -v node) diff --git a/template/package.json b/template/package.json index 21dc8fe5..11b1dd86 100644 --- a/template/package.json +++ b/template/package.json @@ -10,27 +10,27 @@ "lint": "eslint . --ext .js,.jsx,.ts,.tsx" }, "dependencies": { - "react": "17.0.2", - "react-native": "0.68.2" + "react": "18.0.0", + "react-native": "0.69.0" }, "devDependencies": { "@babel/core": "^7.12.9", "@babel/runtime": "^7.12.5", "@react-native-community/eslint-config": "^2.0.0", "@types/jest": "^26.0.23", - "@types/react-native": "^0.67.3", - "@types/react-test-renderer": "^17.0.1", - "@typescript-eslint/eslint-plugin": "^5.17.0", - "@typescript-eslint/parser": "^5.17.0", + "@types/react-native": "^0.68.0", + "@types/react-test-renderer": "^18.0.0", + "@typescript-eslint/eslint-plugin": "^5.29.0", + "@typescript-eslint/parser": "^5.29.0", "babel-jest": "^26.6.3", "eslint": "^7.32.0", "jest": "^26.6.3", - "metro-react-native-babel-preset": "^0.67.0", - "react-test-renderer": "17.0.2", + "metro-react-native-babel-preset": "^0.70.3", + "react-test-renderer": "18.0.0", "typescript": "^4.4.4" }, "resolutions": { - "@types/react": "^17" + "@types/react": "^18" }, "jest": { "preset": "react-native", diff --git a/template/tsconfig.json b/template/tsconfig.json index 80379e90..77163506 100644 --- a/template/tsconfig.json +++ b/template/tsconfig.json @@ -13,7 +13,7 @@ /* Language and Environment */ "target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - "lib": ["es2017"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["es2019"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ "jsx": "react-native", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */