From 14b7a9bca8f5970ef8112869ef6c0c674cfac998 Mon Sep 17 00:00:00 2001 From: Emily Xiong Date: Wed, 5 Jul 2023 12:40:37 -0400 Subject: [PATCH] feat(react-native): upgrade react-native to 0.72.1 --- .../packages/expo/executors/build.json | 3 +- .../react-native/executors/build-android.json | 17 +- .../react-native/executors/build-ios.json | 13 +- .../react-native/executors/pod-install.json | 12 +- .../react-native/executors/run-android.json | 12 +- .../react-native/executors/run-ios.json | 9 +- e2e/expo/src/expo.test.ts | 8 +- package.json | 3 +- .../application/application.spec.ts | 12 - .../files/app/.detoxrc.json.template | 18 - .../application/lib/get-targets.spec.ts | 13 +- .../generators/application/lib/get-targets.ts | 11 +- packages/expo/migrations.json | 65 ++ packages/expo/package.json | 5 +- packages/expo/plugins/with-nx-metro.ts | 34 +- .../executors/build-list/build-list.impl.ts | 6 +- .../expo/src/executors/build/build.impl.ts | 15 +- packages/expo/src/executors/build/schema.json | 3 +- .../src/executors/download/download.impl.ts | 1 + .../src/executors/prebuild/prebuild.impl.ts | 4 +- packages/expo/src/executors/run/run.impl.ts | 9 +- .../application/application.spec.ts | 36 - packages/expo/src/utils/versions.ts | 28 +- packages/react-native/migrations.json | 72 ++ packages/react-native/package.json | 5 +- .../react-native/plugins/with-nx-metro.ts | 33 +- .../build-android/build-android.impl.ts | 85 +- .../src/executors/build-android/schema.d.ts | 6 +- .../src/executors/build-android/schema.json | 19 +- .../src/executors/build-ios/build-ios.impl.ts | 103 +-- .../src/executors/build-ios/schema.d.ts | 2 + .../src/executors/build-ios/schema.json | 11 +- .../src/executors/bundle/bundle.impl.ts | 45 +- .../executors/pod-install/pod-install.impl.ts | 2 +- .../src/executors/pod-install/schema.d.ts | 4 +- .../src/executors/pod-install/schema.json | 12 +- .../executors/run-android/run-android.impl.ts | 72 +- .../src/executors/run-android/schema.json | 14 +- .../src/executors/run-ios/run-ios.impl.ts | 85 +- .../src/executors/run-ios/schema.json | 9 +- .../src/executors/start/start.impl.ts | 70 +- .../src/generators/application/application.ts | 6 - .../application/files/app/.ruby-version | 1 - .../application/files/app/Gemfile.template | 4 +- .../app/android/app/build.gradle.template | 51 +- .../MainActivity.java.template | 7 +- .../res/drawable/rn_edit_text_material.xml | 2 +- .../files/app/android/build.gradle.template | 2 +- .../files/app/android/gradle.properties | 2 +- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 61574 bytes .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../application/files/app/android/gradlew.bat | 15 +- .../files/app/android/gradlew.template | 18 +- .../app/android/settings.gradle.template | 3 +- .../files/app/ios/Podfile.template | 14 +- .../project.pbxproj.template | 8 +- .../ios/__className__/AppDelegate.mm.template | 10 - .../files/app/metro.config.js.template | 67 +- .../files/app/package.json.template | 1 + .../generators/application/lib/add-project.ts | 7 + .../react-native/src/generators/init/init.ts | 4 +- ...age.json__tmpl__ => package.json.template} | 0 ...ig.json__tmpl__ => tsconfig.json.template} | 0 ...son__tmpl__ => tsconfig.lib.json.template} | 0 .../src/generators/library/library.ts | 1 - .../update-16-6-0/add-depends-on.ts | 46 + .../react-native/src/utils/get-cli-options.ts | 4 +- .../src/utils/pod-install-task.ts | 38 +- packages/react-native/src/utils/versions.ts | 19 +- pnpm-lock.yaml | 802 ++++++++++++++---- 70 files changed, 1352 insertions(+), 769 deletions(-) delete mode 100644 packages/react-native/src/generators/application/files/app/.ruby-version rename packages/react-native/src/generators/library/files/lib/{package.json__tmpl__ => package.json.template} (100%) rename packages/react-native/src/generators/library/files/lib/{tsconfig.json__tmpl__ => tsconfig.json.template} (100%) rename packages/react-native/src/generators/library/files/lib/{tsconfig.lib.json__tmpl__ => tsconfig.lib.json.template} (100%) create mode 100644 packages/react-native/src/migrations/update-16-6-0/add-depends-on.ts diff --git a/docs/generated/packages/expo/executors/build.json b/docs/generated/packages/expo/executors/build.json index c1bc9395e445f3..7d5fc37afc68f8 100644 --- a/docs/generated/packages/expo/executors/build.json +++ b/docs/generated/packages/expo/executors/build.json @@ -46,7 +46,8 @@ }, "output": { "type": "string", - "description": "Output path for local build" + "description": "Output path for local build", + "examples": ["../../dist/MyApp.tar.gz", "../../dist"] }, "wait": { "type": "boolean", diff --git a/docs/generated/packages/react-native/executors/build-android.json b/docs/generated/packages/react-native/executors/build-android.json index cdac5b307debcd..ac0a322517e40e 100644 --- a/docs/generated/packages/react-native/executors/build-android.json +++ b/docs/generated/packages/react-native/executors/build-android.json @@ -53,8 +53,10 @@ "default": 8081 }, "tasks": { - "type": "array", - "items": { "type": "string" }, + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.", "examples": [ "assembleDebug", @@ -71,8 +73,12 @@ "default": false }, "extraParams": { - "type": "string", - "description": "Custom params passed to gradle build command" + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], + "description": "Custom params passed to gradle build command", + "examples": ["-x lint -x test"] }, "interactive": { "type": "boolean", @@ -81,7 +87,8 @@ "sync": { "type": "boolean", "description": "Syncs npm dependencies to `package.json` (for React Native autolink).", - "default": true + "default": true, + "x-deprecated": "Add sync-deps to dependsOn instead" }, "resetCache": { "type": "boolean", diff --git a/docs/generated/packages/react-native/executors/build-ios.json b/docs/generated/packages/react-native/executors/build-ios.json index 9f1d67083d6010..8f0e527ea072d8 100644 --- a/docs/generated/packages/react-native/executors/build-ios.json +++ b/docs/generated/packages/react-native/executors/build-ios.json @@ -11,11 +11,7 @@ "presets": [ { "name": "Build iOS for a simulator", "keys": ["simulator"] }, { "name": "Build iOS for a device", "keys": ["device"] }, - { "name": "Build iOS for a device with udid", "keys": ["udid"] }, - { - "name": "Run `pod install` before building iOS app", - "keys": ["install"] - } + { "name": "Build iOS for a device with udid", "keys": ["udid"] } ], "properties": { "simulator": { @@ -72,17 +68,22 @@ "description": "Explicitly select which scheme and configuration to use before running a build" }, "extraParams": { - "type": "string", + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Custom params that will be passed to xcodebuild command." }, "install": { "type": "boolean", "description": "Runs `pod install` for native modules before building iOS app.", + "x-deprecated": "Add pod-install to dependsOn in project.json for this target instead", "default": true }, "sync": { "type": "boolean", "description": "Syncs npm dependencies to `package.json` (for React Native autolink).", + "x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead", "default": true }, "resetCache": { diff --git a/docs/generated/packages/react-native/executors/pod-install.json b/docs/generated/packages/react-native/executors/pod-install.json index da7c4b7f32ed18..2e4f9beae68472 100644 --- a/docs/generated/packages/react-native/executors/pod-install.json +++ b/docs/generated/packages/react-native/executors/pod-install.json @@ -12,9 +12,19 @@ "type": "object", "properties": { "buildFolder": { - "description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory", + "description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory.", "type": "string", "default": "./build" + }, + "repoUpdate": { + "description": "Force running `pod repo update` before install.", + "type": "boolean", + "default": false + }, + "deployment": { + "description": "Disallow any changes to the Podfile or the Podfile.lock during installation.", + "type": "boolean", + "default": false } }, "required": ["buildFolder"], diff --git a/docs/generated/packages/react-native/executors/run-android.json b/docs/generated/packages/react-native/executors/run-android.json index 1f64e92ced64d8..cf0a67aa56360a 100644 --- a/docs/generated/packages/react-native/executors/run-android.json +++ b/docs/generated/packages/react-native/executors/run-android.json @@ -77,8 +77,10 @@ "default": 8081 }, "tasks": { - "type": "array", - "items": { "type": "string" }, + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.", "examples": [ "assembleDebug", @@ -95,7 +97,10 @@ "default": false }, "extraParams": { - "type": "string", + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Custom params passed to gradle build command" }, "interactive": { @@ -105,6 +110,7 @@ "sync": { "type": "boolean", "description": "Syncs npm dependencies to `package.json` (for React Native autolink).", + "x-deprecated": "Add sync-deps to dependsOn for this target in project.json instead", "default": true }, "resetCache": { diff --git a/docs/generated/packages/react-native/executors/run-ios.json b/docs/generated/packages/react-native/executors/run-ios.json index 58f619d5169ac2..70f44ee18a4262 100644 --- a/docs/generated/packages/react-native/executors/run-ios.json +++ b/docs/generated/packages/react-native/executors/run-ios.json @@ -81,17 +81,22 @@ "description": "Explicitly select which scheme and configuration to use before running a build" }, "extraParams": { - "type": "string", + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Custom params that will be passed to xcodebuild command." }, "install": { "type": "boolean", "description": "Runs `pod install` for native modules before building iOS app.", - "default": true + "default": true, + "x-deprecated": "Add `pod-install` to dependsOn for this target in project.json instead." }, "sync": { "type": "boolean", "description": "Syncs npm dependencies to `package.json` (for React Native autolink).", + "x-deprecated": "Add `sync-deps` to dependsOn for this target in project.json instead.", "default": true }, "resetCache": { diff --git a/e2e/expo/src/expo.test.ts b/e2e/expo/src/expo.test.ts index 139fb29b112fff..37c75fac4d12b6 100644 --- a/e2e/expo/src/expo.test.ts +++ b/e2e/expo/src/expo.test.ts @@ -92,15 +92,13 @@ describe('expo', () => { expect(prebuildResult.combinedOutput).toContain('Config synced'); }); - // TODO(emily): expo-cli always fetches the latest version of react native - // re-enable it when expo-cli is fixed - xit('should install', async () => { + it('should install', async () => { // run install command const installResults = await runCLIAsync( - `install ${appName} --no-interactive --check` + `install ${appName} --no-interactive` ); expect(installResults.combinedOutput).toContain( - 'Dependencies are up to date' + 'Successfully ran target install' ); }); diff --git a/package.json b/package.json index 72295477ea91c1..4ae9ea2cf17125 100644 --- a/package.json +++ b/package.json @@ -204,7 +204,8 @@ "magic-string": "~0.26.2", "markdown-factory": "^0.0.6", "memfs": "^3.0.1", - "metro-resolver": "^0.74.1", + "metro-config": "0.76.5", + "metro-resolver": "0.76.5", "mini-css-extract-plugin": "~2.4.7", "minimatch": "3.0.5", "next-sitemap": "^3.1.10", diff --git a/packages/detox/src/generators/application/application.spec.ts b/packages/detox/src/generators/application/application.spec.ts index ef4ff058914a52..08e5f556b14ffd 100644 --- a/packages/detox/src/generators/application/application.spec.ts +++ b/packages/detox/src/generators/application/application.spec.ts @@ -342,12 +342,6 @@ describe('detox application generator', () => { 'cd ../../../my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug', type: 'android.apk', }, - 'android.eas': { - binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.apk', - build: - 'npx nx run my-dir-my-app:download --platform android --distribution simulator --output=../../../my-dir/my-app/dist/', - type: 'android.apk', - }, 'android.local': { binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.apk', build: @@ -368,12 +362,6 @@ describe('detox application generator', () => { "cd ../../../my-dir/my-app/ios && xcodebuild -workspace MyDirMyApp.xcworkspace -scheme MyDirMyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet", type: 'ios.app', }, - 'ios.eas': { - binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.app', - build: - 'npx nx run my-dir-my-app:download --platform ios --distribution simulator --output=../../../my-dir/my-app/dist/', - type: 'ios.app', - }, 'ios.local': { binaryPath: '../../../my-dir/my-app/dist/MyDirMyApp.app', build: diff --git a/packages/detox/src/generators/application/files/app/.detoxrc.json.template b/packages/detox/src/generators/application/files/app/.detoxrc.json.template index 32023673a5f2ed..622d7e779da76e 100644 --- a/packages/detox/src/generators/application/files/app/.detoxrc.json.template +++ b/packages/detox/src/generators/application/files/app/.detoxrc.json.template @@ -20,11 +20,6 @@ "binaryPath": "<%= offsetFromRoot %><%= appRoot %>/ios/build/Build/Products/Release-iphonesimulator/<%= appClassName %>.app" }, <% if (framework === 'expo') { %> - "ios.eas": { - "type": "ios.app", - "build": "<%= exec %> nx run <%= appFileName %>:download --platform ios --distribution simulator --output=<%= offsetFromRoot %><%= appRoot %>/dist/", - "binaryPath": "<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.app" - }, "ios.local": { "type": "ios.app", "build": "<%= exec %> nx run <%= appFileName %>:build --platform ios --profile preview --wait --local --no-interactive --output=<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.tar.gz", @@ -42,11 +37,6 @@ "binaryPath": "<%= offsetFromRoot %><%= appRoot %>/android/app/build/outputs/apk/release/app-release.apk" }, <% if (framework === 'expo') { %> - "android.eas": { - "type": "android.apk", - "build": "<%= exec %> nx run <%= appFileName %>:download --platform android --distribution simulator --output=<%= offsetFromRoot %><%= appRoot %>/dist/", - "binaryPath": "<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.apk" - }, "android.local": { "type": "android.apk", "build": "<%= exec %> nx run <%= appFileName %>:build --platform android --profile preview --wait --local --no-interactive --output=<%= offsetFromRoot %><%= appRoot %>/dist/<%= appExpoName %>.apk", @@ -78,10 +68,6 @@ "app": "ios.debug" }, <% if (framework === 'expo') { %> - "ios.sim.eas": { - "device": "simulator", - "app": "ios.eas" - }, "ios.sim.local": { "device": "simulator", "app": "ios.local" @@ -96,10 +82,6 @@ "app": "android.debug" }, <% if (framework === 'expo') { %> - "android.emu.eas": { - "device": "emulator", - "app": "android.eas" - }, "android.emu.local": { "device": "emulator", "app": "android.local" diff --git a/packages/detox/src/generators/application/lib/get-targets.spec.ts b/packages/detox/src/generators/application/lib/get-targets.spec.ts index 4ffddd609da9ae..d8a35dedd8347e 100644 --- a/packages/detox/src/generators/application/lib/get-targets.spec.ts +++ b/packages/detox/src/generators/application/lib/get-targets.spec.ts @@ -4,14 +4,10 @@ describe('getTargets', () => { it('should return ios test target for expo projects', () => { expect(expoTestTarget('ios.sim', 'test')).toEqual({ options: { - detoxConfiguration: 'ios.sim.eas', - buildTarget: 'test:build-ios', + detoxConfiguration: 'ios.sim.local', + buildTarget: 'test:build-ios:local', }, configurations: { - local: { - detoxConfiguration: 'ios.sim.local', - buildTarget: 'test:build-ios:local', - }, bare: { detoxConfiguration: 'ios.sim.debug', buildTarget: 'test:build-ios:bare', @@ -27,12 +23,9 @@ describe('getTargets', () => { it('should return ios build target for expo projects', () => { expect(expoBuildTarget('ios.sim')).toEqual({ options: { - detoxConfiguration: 'ios.sim.eas', + detoxConfiguration: 'ios.sim.local', }, configurations: { - local: { - detoxConfiguration: 'ios.sim.local', - }, bare: { detoxConfiguration: 'ios.sim.debug', }, diff --git a/packages/detox/src/generators/application/lib/get-targets.ts b/packages/detox/src/generators/application/lib/get-targets.ts index b2bee0d29063d8..b1cbfc4aa0f002 100644 --- a/packages/detox/src/generators/application/lib/get-targets.ts +++ b/packages/detox/src/generators/application/lib/get-targets.ts @@ -14,12 +14,9 @@ export function reactNativeBuildTarget(platform: 'ios.sim' | 'android.emu') { export function expoBuildTarget(platform: 'ios.sim' | 'android.emu') { return { options: { - detoxConfiguration: `${platform}.eas`, + detoxConfiguration: `${platform}.local`, }, configurations: { - local: { - detoxConfiguration: `${platform}.local`, - }, bare: { detoxConfiguration: `${platform}.debug`, }, @@ -58,14 +55,10 @@ export function expoTestTarget( return { options: { - detoxConfiguration: `${platform}.eas`, + detoxConfiguration: `${platform}.local`, buildTarget: `${e2eName}:build-${buildPlatform}`, }, configurations: { - local: { - detoxConfiguration: `${platform}.local`, - buildTarget: `${e2eName}:build-${buildPlatform}:local`, - }, bare: { detoxConfiguration: `${platform}.debug`, buildTarget: `${e2eName}:build-${buildPlatform}:bare`, diff --git a/packages/expo/migrations.json b/packages/expo/migrations.json index 1dfe1357644241..97450e66091b93 100644 --- a/packages/expo/migrations.json +++ b/packages/expo/migrations.json @@ -855,6 +855,71 @@ "alwaysAddToPackageJson": false } } + }, + "16.6.0": { + "version": "16.6.0-beta.0", + "packages": { + "expo": { + "version": "^49.0.0-beta.5", + "alwaysAddToPackageJson": false + }, + "@expo/metro-config": { + "version": "~0.10.6", + "alwaysAddToPackageJson": false + }, + "expo-splash-screen": { + "version": "~0.20.3", + "alwaysAddToPackageJson": false + }, + "expo-status-bar": { + "version": "~1.6.0", + "alwaysAddToPackageJson": false + }, + "expo-updates": { + "version": "~0.18.7", + "alwaysAddToPackageJson": false + }, + "@expo/cli": { + "version": "~0.10.7", + "alwaysAddToPackageJson": false + }, + "eas-cli": { + "version": "~3.15.0", + "alwaysAddToPackageJson": false + }, + "babel-preset-expo": { + "version": "~9.5.0", + "alwaysAddToPackageJson": false + }, + "jest-expo": { + "version": "~49.0.0", + "alwaysAddToPackageJson": false + }, + "metro-resolver": { + "version": "0.76.5", + "alwaysAddToPackageJson": false + }, + "metro": { + "version": "0.76.5", + "alwaysAddToPackageJson": false + }, + "react-native": { + "version": "0.72.1", + "alwaysAddToPackageJson": false + }, + "@types/react-native": { + "version": "0.72.2", + "alwaysAddToPackageJson": false + }, + "react-native-web": { + "version": "~0.19.6", + "alwaysAddToPackageJson": false + }, + "react-native-svg": { + "version": "13.9.0", + "alwaysAddToPackageJson": false + } + } } } } diff --git a/packages/expo/package.json b/packages/expo/package.json index 50ac01e23aace7..1035958cb3cd03 100644 --- a/packages/expo/package.json +++ b/packages/expo/package.json @@ -29,7 +29,8 @@ "chalk": "^4.1.0", "enhanced-resolve": "^5.8.3", "fs-extra": "^11.1.0", - "metro-resolver": "^0.74.1", + "metro-config": "0.76.5", + "metro-resolver": "0.76.5", "node-fetch": "^2.6.7", "tar-fs": "^2.1.1", "tsconfig-paths": "^4.1.2", @@ -43,7 +44,7 @@ "@nx/webpack": "file:../webpack" }, "peerDependencies": { - "expo": "^48.0.19" + "expo": ">= 49.0.0" }, "builders": "./executors.json", "ng-update": { diff --git a/packages/expo/plugins/with-nx-metro.ts b/packages/expo/plugins/with-nx-metro.ts index 81ac08570064c1..943886babbb82d 100644 --- a/packages/expo/plugins/with-nx-metro.ts +++ b/packages/expo/plugins/with-nx-metro.ts @@ -1,4 +1,6 @@ import { workspaceLayout, workspaceRoot } from '@nx/devkit'; +import { mergeConfig } from 'metro-config'; +import type { MetroConfig } from 'metro-config'; import { join } from 'path'; import { existsSync } from 'fs-extra'; @@ -7,35 +9,39 @@ import { getResolveRequest } from './metro-resolver'; interface WithNxOptions { debug?: boolean; extensions?: string[]; + /** + * @deprecated in the metro.config.js, pass in to the getDefaultConfig instead: getDefaultConfig(__dirname) + */ projectRoot?: string; watchFolders?: string[]; } -export function withNxMetro(config: any, opts: WithNxOptions = {}) { +export async function withNxMetro( + userConfig: MetroConfig, + opts: WithNxOptions = {} +) { const extensions = ['', 'ts', 'tsx', 'js', 'jsx', 'json']; if (opts.debug) process.env.NX_REACT_NATIVE_DEBUG = 'true'; if (opts.extensions) extensions.push(...opts.extensions); - config.projectRoot = opts.projectRoot || workspaceRoot; - - // Add support for paths specified by tsconfig - config.resolver = { - ...config.resolver, - resolveRequest: getResolveRequest(extensions), - }; - - let watchFolders = config.watchFolders || []; - watchFolders = watchFolders.concat([ + let watchFolders = [ join(workspaceRoot, 'node_modules'), join(workspaceRoot, workspaceLayout().libsDir), join(workspaceRoot, 'packages'), - ]); + join(workspaceRoot, '.storybook'), + ]; if (opts.watchFolders?.length) { watchFolders = watchFolders.concat(opts.watchFolders); } watchFolders = watchFolders.filter((folder) => existsSync(folder)); - config.watchFolders = watchFolders; - return config; + const nxConfig: MetroConfig = { + resolver: { + resolveRequest: getResolveRequest(extensions), + }, + watchFolders, + }; + + return mergeConfig(userConfig, nxConfig); } diff --git a/packages/expo/src/executors/build-list/build-list.impl.ts b/packages/expo/src/executors/build-list/build-list.impl.ts index 65a90bffa5003a..1f2829a6f0ce78 100644 --- a/packages/expo/src/executors/build-list/build-list.impl.ts +++ b/packages/expo/src/executors/build-list/build-list.impl.ts @@ -1,5 +1,5 @@ import { ExecutorContext, logger, names } from '@nx/devkit'; -import { join } from 'path'; +import { resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; @@ -42,10 +42,10 @@ export function runCliBuildList( ): Promise { return new Promise((resolve, reject) => { childProcess = fork( - join(workspaceRoot, './node_modules/eas-cli/bin/run'), + require.resolve('eas-cli/bin/run'), ['build:list', ...createBuildListOptions(options)], { - cwd: join(workspaceRoot, projectRoot), + cwd: pathResolve(workspaceRoot, projectRoot), env: process.env, stdio: ['inherit', 'pipe', 'inherit', 'ipc'], // only stream stdout on child process } diff --git a/packages/expo/src/executors/build/build.impl.ts b/packages/expo/src/executors/build/build.impl.ts index fc89e7684c7424..011cebd817ef9c 100644 --- a/packages/expo/src/executors/build/build.impl.ts +++ b/packages/expo/src/executors/build/build.impl.ts @@ -1,5 +1,5 @@ import { ExecutorContext, names } from '@nx/devkit'; -import { join, normalize, sep } from 'path'; +import { normalize, sep, resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; @@ -23,18 +23,19 @@ export default async function* buildExecutor( ensureNodeModulesSymlink(context.root, projectRoot); try { + let outputDirectory = ''; // remove the output app if it already existed if (options.local && options.output) { - removeSync(options.output); + const directoryPath = normalize(options.output).split(sep); + directoryPath.pop(); + outputDirectory = directoryPath.join(sep); + removeSync(outputDirectory); } await runCliBuild(context.root, projectRoot, options); // unzip the build if it's a tar.gz if (options.local && options.output && options.output.endsWith('.tar.gz')) { - const directoryPath = normalize(options.output).split(sep); - directoryPath.pop(); - const outputDirectory = directoryPath.join(sep); await unzipBuild(options.output, outputDirectory); } yield { success: true }; @@ -52,10 +53,10 @@ function runCliBuild( ) { return new Promise((resolve, reject) => { childProcess = fork( - join(workspaceRoot, './node_modules/eas-cli/bin/run'), + require.resolve('eas-cli/bin/run'), ['build', ...createBuildOptions(options)], { - cwd: join(workspaceRoot, projectRoot), + cwd: pathResolve(workspaceRoot, projectRoot), env: process.env, } ); diff --git a/packages/expo/src/executors/build/schema.json b/packages/expo/src/executors/build/schema.json index 64c399d6ccffa8..2821cb7c2a29fb 100644 --- a/packages/expo/src/executors/build/schema.json +++ b/packages/expo/src/executors/build/schema.json @@ -55,7 +55,8 @@ }, "output": { "type": "string", - "description": "Output path for local build" + "description": "Output path for local build", + "examples": ["../../dist/MyApp.tar.gz", "../../dist"] }, "wait": { "type": "boolean", diff --git a/packages/expo/src/executors/download/download.impl.ts b/packages/expo/src/executors/download/download.impl.ts index 28dc180b427580..6d44353388e7a8 100644 --- a/packages/expo/src/executors/download/download.impl.ts +++ b/packages/expo/src/executors/download/download.impl.ts @@ -28,6 +28,7 @@ export interface ReactNativeDownloadOutput { const streamPipeline = promisify(pipeline); /** + * @deprecated this executor is to be removed in NX 17. It is no longer used. * This executor downloads the latest EAS build. * It calls the build list executor to list EAS builds with options passed in. */ diff --git a/packages/expo/src/executors/prebuild/prebuild.impl.ts b/packages/expo/src/executors/prebuild/prebuild.impl.ts index 2747473cc804e5..05de40d8b7db71 100644 --- a/packages/expo/src/executors/prebuild/prebuild.impl.ts +++ b/packages/expo/src/executors/prebuild/prebuild.impl.ts @@ -27,7 +27,7 @@ export default async function* prebuildExecutor( if (options.install) { await installAsync(context.root, {}); if (options.platform === 'ios') { - await podInstall(join(context.root, projectRoot, 'ios')); + podInstall(join(context.root, projectRoot, 'ios')); } } @@ -48,7 +48,7 @@ export function prebuildAsync( ): Promise { return new Promise((resolve, reject) => { childProcess = fork( - join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'), + require.resolve('@expo/cli/build/bin/cli'), ['prebuild', ...createPrebuildOptions(options), '--no-install'], { cwd: join(workspaceRoot, projectRoot), env: process.env } ); diff --git a/packages/expo/src/executors/run/run.impl.ts b/packages/expo/src/executors/run/run.impl.ts index f2075f1e2c2874..958e2b3ab7082d 100644 --- a/packages/expo/src/executors/run/run.impl.ts +++ b/packages/expo/src/executors/run/run.impl.ts @@ -1,5 +1,5 @@ import { ExecutorContext, names } from '@nx/devkit'; -import { join } from 'path'; +import { join, resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; import { platform } from 'os'; import { existsSync } from 'fs-extra'; @@ -53,7 +53,7 @@ export default async function* runExecutor( if (options.install) { await installAsync(context.root, {}); if (options.platform === 'ios') { - await podInstall(join(context.root, projectRoot, 'ios')); + podInstall(join(context.root, projectRoot, 'ios')); } } @@ -75,10 +75,11 @@ function runCliRun( ) { return new Promise((resolve, reject) => { childProcess = fork( - join(workspaceRoot, './node_modules/@expo/cli/build/bin/cli'), + require.resolve('@expo/cli/build/bin/cli'), ['run:' + options.platform, ...createRunOptions(options), '--no-install'], // pass in no-install to prevent node_modules install { - cwd: projectRoot, + cwd: pathResolve(workspaceRoot, projectRoot), + env: process.env, } ); diff --git a/packages/expo/src/generators/application/application.spec.ts b/packages/expo/src/generators/application/application.spec.ts index 709303c2549974..2ce626375223cb 100644 --- a/packages/expo/src/generators/application/application.spec.ts +++ b/packages/expo/src/generators/application/application.spec.ts @@ -121,12 +121,6 @@ describe('app', () => { 'cd ../../../apps/my-dir/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug', type: 'android.apk', }, - 'android.eas': { - binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.apk', - build: - 'npx nx run my-app:download --platform android --distribution simulator --output=../../../apps/my-dir/my-app/dist/', - type: 'android.apk', - }, 'android.local': { binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.apk', build: @@ -147,12 +141,6 @@ describe('app', () => { "cd ../../../apps/my-dir/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet", type: 'ios.app', }, - 'ios.eas': { - binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.app', - build: - 'npx nx run my-app:download --platform ios --distribution simulator --output=../../../apps/my-dir/my-app/dist/', - type: 'ios.app', - }, 'ios.local': { binaryPath: '../../../apps/my-dir/my-app/dist/MyApp.app', build: @@ -196,12 +184,6 @@ describe('app', () => { 'cd ../../apps/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug', type: 'android.apk', }, - 'android.eas': { - binaryPath: '../../apps/my-app/dist/MyApp.apk', - build: - 'npx nx run my-app:download --platform android --distribution simulator --output=../../apps/my-app/dist/', - type: 'android.apk', - }, 'android.local': { binaryPath: '../../apps/my-app/dist/MyApp.apk', build: @@ -222,12 +204,6 @@ describe('app', () => { "cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet", type: 'ios.app', }, - 'ios.eas': { - binaryPath: '../../apps/my-app/dist/MyApp.app', - build: - 'npx nx run my-app:download --platform ios --distribution simulator --output=../../apps/my-app/dist/', - type: 'ios.app', - }, 'ios.local': { binaryPath: '../../apps/my-app/dist/MyApp.app', build: @@ -272,12 +248,6 @@ describe('app', () => { 'cd ../../apps/my-app/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug', type: 'android.apk', }, - 'android.eas': { - binaryPath: '../../apps/my-app/dist/myappname.apk', - build: - 'npx nx run my-app:download --platform android --distribution simulator --output=../../apps/my-app/dist/', - type: 'android.apk', - }, 'android.local': { binaryPath: '../../apps/my-app/dist/myappname.apk', build: @@ -298,12 +268,6 @@ describe('app', () => { "cd ../../apps/my-app/ios && xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Debug -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14' -derivedDataPath ./build -quiet", type: 'ios.app', }, - 'ios.eas': { - binaryPath: '../../apps/my-app/dist/myappname.app', - build: - 'npx nx run my-app:download --platform ios --distribution simulator --output=../../apps/my-app/dist/', - type: 'ios.app', - }, 'ios.local': { binaryPath: '../../apps/my-app/dist/myappname.app', build: diff --git a/packages/expo/src/utils/versions.ts b/packages/expo/src/utils/versions.ts index a494bd29a0ac28..a876fe1c67c136 100644 --- a/packages/expo/src/utils/versions.ts +++ b/packages/expo/src/utils/versions.ts @@ -1,28 +1,28 @@ export const nxVersion = require('../../package.json').version; -export const expoVersion = '48.0.19'; -export const expoMetroConfigVersion = '0.7.1'; -export const expoSplashScreenVersion = '~0.18.2'; -export const expoStatusBarVersion = '~1.4.4'; -export const expoUpdatesVersion = '~0.16.4'; -export const expoCliVersion = '~0.7.3'; // @expo/cli -export const easCliVersion = '~3.13.3'; -export const babelPresetExpoVersion = '~9.3.2'; +export const expoVersion = '49.0.0'; +export const expoMetroConfigVersion = '~0.10.6'; +export const expoSplashScreenVersion = '~0.20.3'; +export const expoStatusBarVersion = '~1.6.0'; +export const expoUpdatesVersion = '~0.18.7'; +export const expoCliVersion = '~0.10.7'; // @expo/cli +export const easCliVersion = '~3.15.0'; +export const babelPresetExpoVersion = '~9.5.0'; export const reactVersion = '18.2.0'; export const reactDomVersion = '18.2.0'; export const reactTestRendererVersion = '18.2.0'; export const typesReactVersion = '18.0.28'; -export const reactNativeVersion = '0.71.8'; -export const typesReactNativeVersion = '0.71.7'; -export const reactNativeWebVersion = '~0.18.12'; +export const reactNativeVersion = '0.72.1'; +export const typesReactNativeVersion = '0.72.2'; +export const reactNativeWebVersion = '~0.19.6'; export const reactNativeSvgTransformerVersion = '1.0.0'; -export const reactNativeSvgVersion = '13.4.0'; +export const reactNativeSvgVersion = '13.9.0'; -export const metroVersion = '0.74.1'; +export const metroVersion = '0.76.5'; export const testingLibraryReactNativeVersion = '12.1.2'; export const testingLibraryJestNativeVersion = '5.4.2'; -export const jestExpoVersion = '~48.0.2'; +export const jestExpoVersion = '~49.0.0'; diff --git a/packages/react-native/migrations.json b/packages/react-native/migrations.json index 2615b50013cf0e..39787e0c8944c9 100644 --- a/packages/react-native/migrations.json +++ b/packages/react-native/migrations.json @@ -89,6 +89,12 @@ "version": "16.1.0-beta.0", "description": "Upgrade @storybook/react-native to 6.5", "implementation": "./src/migrations/update-16-1-0/upgrade-storybook-6-5" + }, + "update-16-6-0-add-dependsOn": { + "cli": "nx", + "version": "16.6.0-beta.0", + "description": "Add dependsOn like ensure-symlink or sync-deps to targets", + "implementation": "./src/migrations/update-16-6-0/add-depends-on" } }, "packageJsonUpdates": { @@ -1348,6 +1354,72 @@ "alwaysAddToPackageJson": false } } + }, + "16.6.0": { + "version": "16.6.0-beta.0", + "packages": { + "react-native": { + "version": "0.72.1", + "alwaysAddToPackageJson": false + }, + "@types/react-native": { + "version": "0.72.2", + "alwaysAddToPackageJson": false + }, + "metro": { + "version": "0.76.5", + "alwaysAddToPackageJson": false + }, + "metro-resolver": { + "version": "0.76.5", + "alwaysAddToPackageJson": false + }, + "metro-config": { + "version": "0.76.5", + "alwaysAddToPackageJson": false + }, + "metro-react-native-babel-preset": { + "version": "0.76.5", + "alwaysAddToPackageJson": false + }, + "metro-babel-register": { + "version": "0.76.5", + "alwaysAddToPackageJson": false + }, + "metro-react-native-babel-transformer": { + "version": "0.76.5", + "alwaysAddToPackageJson": false + }, + "@react-native/metro-config": { + "version": "0.72.7", + "alwaysAddToPackageJson": false, + "addToPackageJson": "devDependencies" + }, + "@react-native-community/cli": { + "version": "11.3.3", + "alwaysAddToPackageJson": false + }, + "@react-native-community/cli-platform-android": { + "version": "11.3.3", + "alwaysAddToPackageJson": false + }, + "@react-native-community/cli-platform-ios": { + "version": "11.3.3", + "alwaysAddToPackageJson": false + }, + "@babel/runtime": { + "version": "7.22.6", + "alwaysAddToPackageJson": false + }, + "@react-native-async-storage/async-storage": { + "version": "1.19.0", + "alwaysAddToPackageJson": false + }, + "react-native-safe-area-context": { + "version": "4.6.4", + "alwaysAddToPackageJson": false + } + } } } } diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 0231e5e88d8ef3..b2df964061e338 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -30,7 +30,8 @@ "fs-extra": "^11.1.0", "glob": "7.1.4", "ignore": "^5.0.4", - "metro-resolver": "^0.74.1", + "metro-config": "0.76.5", + "metro-resolver": "0.76.5", "minimatch": "3.0.5", "node-fetch": "^2.6.7", "tsconfig-paths": "^4.1.2", @@ -43,7 +44,7 @@ "@nx/workspace": "file:../workspace" }, "peerDependencies": { - "react-native": ">= 0.71.0" + "react-native": ">= 0.72.0 < 0.73.0" }, "builders": "./executors.json", "ng-update": { diff --git a/packages/react-native/plugins/with-nx-metro.ts b/packages/react-native/plugins/with-nx-metro.ts index 6bf66f767af324..943886babbb82d 100644 --- a/packages/react-native/plugins/with-nx-metro.ts +++ b/packages/react-native/plugins/with-nx-metro.ts @@ -1,4 +1,6 @@ import { workspaceLayout, workspaceRoot } from '@nx/devkit'; +import { mergeConfig } from 'metro-config'; +import type { MetroConfig } from 'metro-config'; import { join } from 'path'; import { existsSync } from 'fs-extra'; @@ -7,36 +9,39 @@ import { getResolveRequest } from './metro-resolver'; interface WithNxOptions { debug?: boolean; extensions?: string[]; + /** + * @deprecated in the metro.config.js, pass in to the getDefaultConfig instead: getDefaultConfig(__dirname) + */ projectRoot?: string; watchFolders?: string[]; } -export function withNxMetro(config: any, opts: WithNxOptions = {}) { +export async function withNxMetro( + userConfig: MetroConfig, + opts: WithNxOptions = {} +) { const extensions = ['', 'ts', 'tsx', 'js', 'jsx', 'json']; if (opts.debug) process.env.NX_REACT_NATIVE_DEBUG = 'true'; if (opts.extensions) extensions.push(...opts.extensions); - config.projectRoot = opts.projectRoot || workspaceRoot; - - // Add support for paths specified by tsconfig - config.resolver = { - ...config.resolver, - resolveRequest: getResolveRequest(extensions), - }; - - let watchFolders = config.watchFolders || []; - watchFolders = watchFolders.concat([ + let watchFolders = [ join(workspaceRoot, 'node_modules'), join(workspaceRoot, workspaceLayout().libsDir), join(workspaceRoot, 'packages'), join(workspaceRoot, '.storybook'), - ]); + ]; if (opts.watchFolders?.length) { watchFolders = watchFolders.concat(opts.watchFolders); } watchFolders = watchFolders.filter((folder) => existsSync(folder)); - config.watchFolders = watchFolders; - return config; + const nxConfig: MetroConfig = { + resolver: { + resolveRequest: getResolveRequest(extensions), + }, + watchFolders, + }; + + return mergeConfig(userConfig, nxConfig); } diff --git a/packages/react-native/src/executors/build-android/build-android.impl.ts b/packages/react-native/src/executors/build-android/build-android.impl.ts index e6082d2d64f537..666294145b693f 100644 --- a/packages/react-native/src/executors/build-android/build-android.impl.ts +++ b/packages/react-native/src/executors/build-android/build-android.impl.ts @@ -1,62 +1,44 @@ -import { ExecutorContext, names } from '@nx/devkit'; -import { join } from 'path'; -import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; +import { ExecutorContext } from '@nx/devkit'; +import { join, resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; import { ReactNativeBuildAndroidOptions } from './schema'; import { chmodAndroidGradlewFiles } from '../../utils/chmod-android-gradle-files'; -import { runCliStart } from '../start/start.impl'; -import { - displayNewlyAddedDepsMessage, - syncDeps, -} from '../sync-deps/sync-deps.impl'; +import startExecutor from '../start/start.impl'; import { getCliOptions } from '../../utils/get-cli-options'; export interface ReactNativeBuildOutput { success: boolean; } -let childProcess: ChildProcess; - export default async function* buildAndroidExecutor( options: ReactNativeBuildAndroidOptions, context: ExecutorContext ): AsyncGenerator { const projectRoot = context.projectsConfigurations.projects[context.projectName].root; - ensureNodeModulesSymlink(context.root, projectRoot); - if (options.sync) { - displayNewlyAddedDepsMessage( - context.projectName, - await syncDeps( - context.projectName, - projectRoot, - context.root, - context.projectGraph - ) - ); - } - chmodAndroidGradlewFiles(join(projectRoot, 'android')); - try { - const tasks = [runCliBuild(context.root, projectRoot, options)]; - if (options.packager && options.mode !== 'release') { - tasks.push( - runCliStart(context.root, projectRoot, { - port: options.port, - resetCache: options.resetCache, - interactive: options.interactive, - }) - ); - } - - await Promise.all(tasks); - yield { success: true }; - } finally { - if (childProcess) { - childProcess.kill(); + if (options.packager && options.mode !== 'release') { + const startResults = startExecutor( + { + port: options.port, + resetCache: options.resetCache, + interactive: true, + }, + context + ); + for await (const result of startResults) { + if (!result.success) { + return result; + } + yield { + success: true, + }; } } + + await runCliBuild(context.root, projectRoot, options); + yield { success: true }; } function runCliBuild( @@ -64,30 +46,37 @@ function runCliBuild( projectRoot: string, options: ReactNativeBuildAndroidOptions ) { - return new Promise((resolve, reject) => { + return new Promise((res, reject) => { /** * Call the react native cli with option `--no-packager` * Not passing '--packager' due to cli will launch start command from the project root */ - childProcess = fork( - join(workspaceRoot, './node_modules/react-native/cli.js'), + const childProcess = fork( + require.resolve('react-native/cli.js'), ['build-android', ...createBuildAndroidOptions(options), '--no-packager'], { - cwd: join(workspaceRoot, projectRoot), + stdio: 'inherit', + cwd: pathResolve(workspaceRoot, projectRoot), env: { ...process.env, RCT_METRO_PORT: options.port.toString() }, } ); - // Ensure the child process is killed when the parent exits - process.on('exit', () => childProcess.kill()); - process.on('SIGTERM', () => childProcess.kill()); + /** + * Ensure the child process is killed when the parent exits + */ + const processExitListener = (signal?: number | NodeJS.Signals) => () => + childProcess.kill(signal); + process.on('exit', processExitListener); + process.on('SIGTERM', processExitListener); + process.on('SIGINT', processExitListener); + process.on('SIGQUIT', processExitListener); childProcess.on('error', (err) => { reject(err); }); childProcess.on('exit', (code) => { if (code === 0) { - resolve(code); + res(childProcess); } else { reject(code); } diff --git a/packages/react-native/src/executors/build-android/schema.d.ts b/packages/react-native/src/executors/build-android/schema.d.ts index 24c8d29ce7401f..14f7dc8618662b 100644 --- a/packages/react-native/src/executors/build-android/schema.d.ts +++ b/packages/react-native/src/executors/build-android/schema.d.ts @@ -1,4 +1,5 @@ // options taken from https://github.com/react-native-community/cli/blob/main/packages/cli-platform-android/src/commands/buildAndroid/index.ts +// https://github.com/react-native-community/cli/blob/main/packages/cli-platform-android/README.md#build-android import { ReactNativeStartOptions } from '../start/schema'; @@ -20,10 +21,9 @@ export interface ReactNativeBuildAndroidOptions // react native options mode: string; // default is debug activeArchOnly: boolean; // default is false - port: number; // default is 8081 - tasks?: Array; + tasks?: string | Array; extraParams?: Array; - interactive?: boolean; + interactive: boolean; // nx options packager: boolean; // default is true diff --git a/packages/react-native/src/executors/build-android/schema.json b/packages/react-native/src/executors/build-android/schema.json index 16284032ae8cbd..a9536f6d540fa3 100644 --- a/packages/react-native/src/executors/build-android/schema.json +++ b/packages/react-native/src/executors/build-android/schema.json @@ -59,10 +59,10 @@ "default": 8081 }, "tasks": { - "type": "array", - "items": { - "type": "string" - }, + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.", "examples": [ "assembleDebug", @@ -79,8 +79,12 @@ "default": false }, "extraParams": { - "type": "string", - "description": "Custom params passed to gradle build command" + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], + "description": "Custom params passed to gradle build command", + "examples": ["-x lint -x test"] }, "interactive": { "type": "boolean", @@ -89,7 +93,8 @@ "sync": { "type": "boolean", "description": "Syncs npm dependencies to `package.json` (for React Native autolink).", - "default": true + "default": true, + "x-deprecated": "Add sync-deps to dependsOn instead" }, "resetCache": { "type": "boolean", diff --git a/packages/react-native/src/executors/build-ios/build-ios.impl.ts b/packages/react-native/src/executors/build-ios/build-ios.impl.ts index 7b58775717f8b9..9816a1afd004a8 100644 --- a/packages/react-native/src/executors/build-ios/build-ios.impl.ts +++ b/packages/react-native/src/executors/build-ios/build-ios.impl.ts @@ -1,25 +1,17 @@ import { ExecutorContext } from '@nx/devkit'; -import { join } from 'path'; +import { resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; import { platform } from 'os'; -import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; -import { - displayNewlyAddedDepsMessage, - syncDeps, -} from '../sync-deps/sync-deps.impl'; -import { podInstall } from '../../utils/pod-install-task'; import { ReactNativeBuildIosOptions } from './schema'; -import { runCliStart } from '../start/start.impl'; +import startExecutor from '../start/start.impl'; import { getCliOptions } from '../../utils/get-cli-options'; export interface ReactNativeBuildIosOutput { success: boolean; } -let childProcess: ChildProcess; - -export default async function* runIosExecutor( +export default async function* buildIosExecutor( options: ReactNativeBuildIosOptions, context: ExecutorContext ): AsyncGenerator { @@ -28,77 +20,64 @@ export default async function* runIosExecutor( } const projectRoot = context.projectsConfigurations.projects[context.projectName].root; - ensureNodeModulesSymlink(context.root, projectRoot); - if (options.sync) { - displayNewlyAddedDepsMessage( - context.projectName, - await syncDeps( - context.projectName, - projectRoot, - context.root, - context.projectGraph - ) - ); - } - if (options.install) { - await podInstall( - join(context.root, projectRoot, 'ios'), - options.buildFolder + if (options.packager && options.mode !== 'Release') { + const startResults = startExecutor( + { + port: options.port, + resetCache: options.resetCache, + interactive: true, + }, + context ); - } - - try { - const tasks = [runCliBuildIOS(context.root, projectRoot, options)]; - if (options.packager && options.mode !== 'Release') { - tasks.push( - runCliStart(context.root, projectRoot, { - port: options.port, - resetCache: options.resetCache, - interactive: options.interactive, - }) - ); - } - - await Promise.all(tasks); - - yield { success: true }; - } finally { - if (childProcess) { - childProcess.kill(); + for await (const result of startResults) { + if (!result.success) { + return result; + } + yield { + success: true, + }; } } + + await runCliBuildIOS(context.root, projectRoot, options); + yield { success: true }; } function runCliBuildIOS( workspaceRoot: string, projectRoot: string, options: ReactNativeBuildIosOptions -) { - return new Promise((resolve, reject) => { - /** - * Call the react native cli with option `--no-packager` - * Not passing '--packager' due to cli will launch start command from the project root - */ - childProcess = fork( - join(workspaceRoot, './node_modules/react-native/cli.js'), - ['build-ios', ...createBuildIOSOptions(options)], +): Promise { + return new Promise((resolve, reject) => { + const childProcess = fork( + require.resolve('react-native/cli.js'), + [ + 'build-ios', + ...createBuildIOSOptions(options), + ...(process.env.NX_VERBOSE_LOGGING === 'true' ? ['--verbose'] : []), + ], { - cwd: join(workspaceRoot, projectRoot), + cwd: pathResolve(workspaceRoot, projectRoot), env: { ...process.env, RCT_METRO_PORT: options.port.toString() }, } ); - // Ensure the child process is killed when the parent exits - process.on('exit', () => childProcess.kill()); - process.on('SIGTERM', () => childProcess.kill()); - + /** + * Ensure the child process is killed when the parent exits + */ + const processExitListener = (signal?: number | NodeJS.Signals) => () => + childProcess.kill(signal); + process.on('exit', processExitListener); + process.on('SIGTERM', processExitListener); + process.on('SIGINT', processExitListener); + process.on('SIGQUIT', processExitListener); childProcess.on('error', (err) => { reject(err); }); childProcess.on('exit', (code) => { if (code === 0) { - resolve(code); + resolve(childProcess); } else { reject(code); } diff --git a/packages/react-native/src/executors/build-ios/schema.d.ts b/packages/react-native/src/executors/build-ios/schema.d.ts index df4fac0ecc331a..5ec1a797a0b009 100644 --- a/packages/react-native/src/executors/build-ios/schema.d.ts +++ b/packages/react-native/src/executors/build-ios/schema.d.ts @@ -17,6 +17,8 @@ export interface ReactNativeBuildIosOptions extends ReactNativeStartOptions { // nx options packager: boolean; // default is true + // @deprecated, add to pod-install to dependsOn install: boolean; // default is true + // @deprecated, add to sync-deps to dependsOn sync: boolean; // default is true } diff --git a/packages/react-native/src/executors/build-ios/schema.json b/packages/react-native/src/executors/build-ios/schema.json index a23017767b4113..77653ad8d81b8e 100644 --- a/packages/react-native/src/executors/build-ios/schema.json +++ b/packages/react-native/src/executors/build-ios/schema.json @@ -17,10 +17,6 @@ { "name": "Build iOS for a device with udid", "keys": ["udid"] - }, - { - "name": "Run `pod install` before building iOS app", - "keys": ["install"] } ], "properties": { @@ -78,17 +74,22 @@ "description": "Explicitly select which scheme and configuration to use before running a build" }, "extraParams": { - "type": "string", + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Custom params that will be passed to xcodebuild command." }, "install": { "type": "boolean", "description": "Runs `pod install` for native modules before building iOS app.", + "x-deprecated": "Add pod-install to dependsOn in project.json for this target instead", "default": true }, "sync": { "type": "boolean", "description": "Syncs npm dependencies to `package.json` (for React Native autolink).", + "x-deprecated": "Add sync-deps to dependsOn in project.json for this target instead", "default": true }, "resetCache": { diff --git a/packages/react-native/src/executors/bundle/bundle.impl.ts b/packages/react-native/src/executors/bundle/bundle.impl.ts index 42f4a9004465f3..64df66ead0b75f 100644 --- a/packages/react-native/src/executors/bundle/bundle.impl.ts +++ b/packages/react-native/src/executors/bundle/bundle.impl.ts @@ -1,18 +1,14 @@ import { createDirectory } from '@nx/workspace/src/utilities/fileutils'; import { names, ExecutorContext } from '@nx/devkit'; -import { dirname, join } from 'path'; +import { dirname, join, resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; -import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; - import { ReactNativeBundleOptions } from './schema'; export interface ReactNativeBundleOutput { success: boolean; } -let childProcess: ChildProcess; - export default async function* bundleExecutor( options: ReactNativeBundleOptions, context: ExecutorContext @@ -23,41 +19,44 @@ export default async function* bundleExecutor( options.bundleOutput = join(context.root, options.bundleOutput); createDirectory(dirname(options.bundleOutput)); - ensureNodeModulesSymlink(context.root, projectRoot); - try { - await runCliBuild(context.root, projectRoot, options); - yield { success: true }; - } finally { - if (childProcess) { - childProcess.kill(); - } - } + await runCliBuild(context.root, projectRoot, options); + yield { success: true }; } function runCliBuild( workspaceRoot: string, projectRoot: string, options: ReactNativeBundleOptions -) { - return new Promise((resolve, reject) => { +): Promise { + return new Promise((resolve, reject) => { const cliOptions = createBundleOptions(options); - childProcess = fork( - join(workspaceRoot, './node_modules/react-native/cli.js'), + const childProcess = fork( + require.resolve('react-native/cli.js'), ['bundle', ...cliOptions], - { cwd: join(workspaceRoot, projectRoot), env: process.env } + { + stdio: 'inherit', + cwd: pathResolve(workspaceRoot, projectRoot), + env: process.env, + } ); - // Ensure the child process is killed when the parent exits - process.on('exit', () => childProcess.kill()); - process.on('SIGTERM', () => childProcess.kill()); + /** + * Ensure the child process is killed when the parent exits + */ + const processExitListener = (signal?: number | NodeJS.Signals) => () => + childProcess.kill(signal); + process.on('exit', processExitListener); + process.on('SIGTERM', processExitListener); + process.on('SIGINT', processExitListener); + process.on('SIGQUIT', processExitListener); childProcess.on('error', (err) => { reject(err); }); childProcess.on('exit', (code) => { if (code === 0) { - resolve(code); + resolve(childProcess); } else { reject(code); } diff --git a/packages/react-native/src/executors/pod-install/pod-install.impl.ts b/packages/react-native/src/executors/pod-install/pod-install.impl.ts index c4a283fca05d4e..8ec0f80cffdb87 100644 --- a/packages/react-native/src/executors/pod-install/pod-install.impl.ts +++ b/packages/react-native/src/executors/pod-install/pod-install.impl.ts @@ -15,7 +15,7 @@ export default async function* podInstall( const projectRoot = context.projectsConfigurations.projects[context.projectName].root; const iosDirectory = join(context.root, projectRoot, 'ios'); - await runPodInstall(iosDirectory, true, options.buildFolder)(); + await runPodInstall(iosDirectory, true, options)(); yield { success: true }; } diff --git a/packages/react-native/src/executors/pod-install/schema.d.ts b/packages/react-native/src/executors/pod-install/schema.d.ts index 11f7664df8e041..41f36baf08d81f 100644 --- a/packages/react-native/src/executors/pod-install/schema.d.ts +++ b/packages/react-native/src/executors/pod-install/schema.d.ts @@ -1,3 +1,5 @@ export interface ReactNativePodInstallOptions { - buildFolder: string; + buildFolder: string; // default is './build' + repoUpdate: boolean; // default is false + deployment: boolean; // default is false } diff --git a/packages/react-native/src/executors/pod-install/schema.json b/packages/react-native/src/executors/pod-install/schema.json index 0cc954d982e9e8..e6e373c4c756fd 100644 --- a/packages/react-native/src/executors/pod-install/schema.json +++ b/packages/react-native/src/executors/pod-install/schema.json @@ -9,9 +9,19 @@ "type": "object", "properties": { "buildFolder": { - "description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory", + "description": "Location for iOS build artifacts. Corresponds to Xcode's \"-derivedDataPath\". Relative to ios directory.", "type": "string", "default": "./build" + }, + "repoUpdate": { + "description": "Force running `pod repo update` before install.", + "type": "boolean", + "default": false + }, + "deployment": { + "description": "Disallow any changes to the Podfile or the Podfile.lock during installation.", + "type": "boolean", + "default": false } }, "required": ["buildFolder"] diff --git a/packages/react-native/src/executors/run-android/run-android.impl.ts b/packages/react-native/src/executors/run-android/run-android.impl.ts index a73b3c197bbb95..6fd04dfe614609 100644 --- a/packages/react-native/src/executors/run-android/run-android.impl.ts +++ b/packages/react-native/src/executors/run-android/run-android.impl.ts @@ -1,14 +1,9 @@ import { ExecutorContext } from '@nx/devkit'; -import { join } from 'path'; +import { join, resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; -import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; -import { - displayNewlyAddedDepsMessage, - syncDeps, -} from '../sync-deps/sync-deps.impl'; import { ReactNativeRunAndroidOptions } from './schema'; -import { runCliStart } from '../start/start.impl'; +import startExecutor, { runCliStart } from '../start/start.impl'; import { chmodAndroidGradlewFiles } from '../../utils/chmod-android-gradle-files'; import { getCliOptions } from '../../utils/get-cli-options'; @@ -24,72 +19,59 @@ export default async function* runAndroidExecutor( ): AsyncGenerator { const projectRoot = context.projectsConfigurations.projects[context.projectName].root; - ensureNodeModulesSymlink(context.root, projectRoot); chmodAndroidGradlewFiles(join(projectRoot, 'android')); - if (options.sync) { - displayNewlyAddedDepsMessage( - context.projectName, - await syncDeps( - context.projectName, - projectRoot, - context.root, - context.projectGraph - ) + await runCliRunAndroid(context.root, projectRoot, options); + if (options.packager && options.mode !== 'Release') { + return startExecutor( + { + port: options.port, + resetCache: options.resetCache, + interactive: true, + }, + context ); } - try { - const tasks = [runCliRunAndroid(context.root, projectRoot, options)]; - if (options.packager) { - tasks.push( - runCliStart(context.root, projectRoot, { - port: options.port, - resetCache: options.resetCache, - interactive: options.interactive, - }) - ); - } - - await Promise.all(tasks); - - yield { success: true }; - } finally { - if (childProcess) { - childProcess.kill(); - } - } + yield { success: true }; } function runCliRunAndroid( workspaceRoot: string, projectRoot: string, options: ReactNativeRunAndroidOptions -) { - return new Promise((resolve, reject) => { +): Promise { + return new Promise((resolve, reject) => { /** * Call the react native cli with option `--no-packager` * Not passing '--packager' due to cli will launch start command from the project root */ childProcess = fork( - join(workspaceRoot, './node_modules/react-native/cli.js'), + require.resolve('react-native/cli.js'), ['run-android', ...createRunAndroidOptions(options), '--no-packager'], { - cwd: join(workspaceRoot, projectRoot), + stdio: 'inherit', + cwd: pathResolve(workspaceRoot, projectRoot), env: { ...process.env, RCT_METRO_PORT: options.port.toString() }, } ); - // Ensure the child process is killed when the parent exits - process.on('exit', () => childProcess.kill()); - process.on('SIGTERM', () => childProcess.kill()); + /** + * Ensure the child process is killed when the parent exits + */ + const processExitListener = (signal?: number | NodeJS.Signals) => () => + childProcess.kill(signal); + process.on('exit', processExitListener); + process.on('SIGTERM', processExitListener); + process.on('SIGINT', processExitListener); + process.on('SIGQUIT', processExitListener); childProcess.on('error', (err) => { reject(err); }); childProcess.on('exit', (code) => { if (code === 0) { - resolve(code); + resolve(childProcess); } else { reject(code); } diff --git a/packages/react-native/src/executors/run-android/schema.json b/packages/react-native/src/executors/run-android/schema.json index 41614a3ea66158..1854d664cd999a 100644 --- a/packages/react-native/src/executors/run-android/schema.json +++ b/packages/react-native/src/executors/run-android/schema.json @@ -77,10 +77,10 @@ "default": 8081 }, "tasks": { - "type": "array", - "items": { - "type": "string" - }, + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Run custom Gradle tasks. By default it's \"assembleDebug\". Will override passed mode and variant arguments.", "examples": [ "assembleDebug", @@ -97,7 +97,10 @@ "default": false }, "extraParams": { - "type": "string", + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Custom params passed to gradle build command" }, "interactive": { @@ -107,6 +110,7 @@ "sync": { "type": "boolean", "description": "Syncs npm dependencies to `package.json` (for React Native autolink).", + "x-deprecated": "Add sync-deps to dependsOn for this target in project.json instead", "default": true }, "resetCache": { diff --git a/packages/react-native/src/executors/run-ios/run-ios.impl.ts b/packages/react-native/src/executors/run-ios/run-ios.impl.ts index 62b4581e7ef755..ae7dfd64a5244a 100644 --- a/packages/react-native/src/executors/run-ios/run-ios.impl.ts +++ b/packages/react-native/src/executors/run-ios/run-ios.impl.ts @@ -1,24 +1,16 @@ import { ExecutorContext } from '@nx/devkit'; -import { join } from 'path'; +import { resolve as pathResolve } from 'path'; import { ChildProcess, fork } from 'child_process'; import { platform } from 'os'; -import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; -import { - displayNewlyAddedDepsMessage, - syncDeps, -} from '../sync-deps/sync-deps.impl'; -import { podInstall } from '../../utils/pod-install-task'; -import { ReactNativeRunIosOptions } from './schema'; -import { runCliStart } from '../start/start.impl'; +import startExecutor from '../start/start.impl'; import { getCliOptions } from '../../utils/get-cli-options'; +import { ReactNativeRunIosOptions } from './schema'; export interface ReactNativeRunIosOutput { success: boolean; } -let childProcess: ChildProcess; - export default async function* runIosExecutor( options: ReactNativeRunIosOptions, context: ExecutorContext @@ -28,77 +20,58 @@ export default async function* runIosExecutor( } const projectRoot = context.projectsConfigurations.projects[context.projectName].root; - ensureNodeModulesSymlink(context.root, projectRoot); - if (options.sync) { - displayNewlyAddedDepsMessage( - context.projectName, - await syncDeps( - context.projectName, - projectRoot, - context.root, - context.projectGraph - ) - ); - } - if (options.install) { - await podInstall( - join(context.root, projectRoot, 'ios'), - options.buildFolder + await runCliRunIOS(context.root, projectRoot, options); + if (options.packager && options.mode !== 'Release') { + return startExecutor( + { + port: options.port, + resetCache: options.resetCache, + interactive: true, + }, + context ); } - try { - const tasks = [runCliRunIOS(context.root, projectRoot, options)]; - if (options.packager && options.mode !== 'Release') { - tasks.push( - runCliStart(context.root, projectRoot, { - port: options.port, - resetCache: options.resetCache, - interactive: options.interactive, - }) - ); - } - - await Promise.all(tasks); - - yield { success: true }; - } finally { - if (childProcess) { - childProcess.kill(); - } - } + yield { success: true }; } function runCliRunIOS( workspaceRoot: string, projectRoot: string, options: ReactNativeRunIosOptions -) { - return new Promise((resolve, reject) => { +): Promise { + return new Promise((resolve, reject) => { /** * Call the react native cli with option `--no-packager` * Not passing '--packager' due to cli will launch start command from the project root */ - childProcess = fork( - join(workspaceRoot, './node_modules/react-native/cli.js'), + const childProcess = fork( + require.resolve('react-native/cli.js'), ['run-ios', ...createRunIOSOptions(options), '--no-packager'], { - cwd: join(workspaceRoot, projectRoot), + stdio: 'inherit', + cwd: pathResolve(workspaceRoot, projectRoot), env: { ...process.env, RCT_METRO_PORT: options.port.toString() }, } ); - // Ensure the child process is killed when the parent exits - process.on('exit', () => childProcess.kill()); - process.on('SIGTERM', () => childProcess.kill()); + /** + * Ensure the child process is killed when the parent exits + */ + const processExitListener = (signal?: number | NodeJS.Signals) => () => + childProcess.kill(signal); + process.on('exit', processExitListener); + process.on('SIGTERM', processExitListener); + process.on('SIGINT', processExitListener); + process.on('SIGQUIT', processExitListener); childProcess.on('error', (err) => { reject(err); }); childProcess.on('exit', (code) => { if (code === 0) { - resolve(code); + resolve(childProcess); } else { reject(code); } diff --git a/packages/react-native/src/executors/run-ios/schema.json b/packages/react-native/src/executors/run-ios/schema.json index ca1182d5b473af..8759a936091a96 100644 --- a/packages/react-native/src/executors/run-ios/schema.json +++ b/packages/react-native/src/executors/run-ios/schema.json @@ -87,17 +87,22 @@ "description": "Explicitly select which scheme and configuration to use before running a build" }, "extraParams": { - "type": "string", + "oneOf": [ + { "type": "array", "items": { "type": "string" } }, + { "type": "string" } + ], "description": "Custom params that will be passed to xcodebuild command." }, "install": { "type": "boolean", "description": "Runs `pod install` for native modules before building iOS app.", - "default": true + "default": true, + "x-deprecated": "Add `pod-install` to dependsOn for this target in project.json instead." }, "sync": { "type": "boolean", "description": "Syncs npm dependencies to `package.json` (for React Native autolink).", + "x-deprecated": "Add `sync-deps` to dependsOn for this target in project.json instead.", "default": true }, "resetCache": { diff --git a/packages/react-native/src/executors/start/start.impl.ts b/packages/react-native/src/executors/start/start.impl.ts index 8155da595bdeb4..be3f602941d285 100644 --- a/packages/react-native/src/executors/start/start.impl.ts +++ b/packages/react-native/src/executors/start/start.impl.ts @@ -1,18 +1,16 @@ import * as chalk from 'chalk'; import { ExecutorContext, logger } from '@nx/devkit'; import { ChildProcess, fork } from 'child_process'; -import { join } from 'path'; +import { resolve as pathResolve } from 'path'; import { ensureNodeModulesSymlink } from '../../utils/ensure-node-modules-symlink'; import { isPackagerRunning } from './lib/is-packager-running'; import { ReactNativeStartOptions } from './schema'; export interface ReactNativeStartOutput { - baseUrl?: string; + port?: number; success: boolean; } -let childProcess: ChildProcess; - export default async function* startExecutor( options: ReactNativeStartOptions, context: ExecutorContext @@ -21,27 +19,23 @@ export default async function* startExecutor( context.projectsConfigurations.projects[context.projectName].root; ensureNodeModulesSymlink(context.root, projectRoot); - try { - const baseUrl = `http://localhost:${options.port}`; - const appName = context.projectName; - logger.info(chalk.cyan(`Packager is ready at ${baseUrl}`)); - logger.info( - `Use ${chalk.bold(`nx run-android ${appName}`)} or ${chalk.bold( - `nx run-ios ${appName}` - )} to run the native app.` - ); + const startProcess = await runCliStart(context.root, projectRoot, options); - await runCliStart(context.root, projectRoot, options); + yield { + port: options.port, + success: true, + }; - yield { - baseUrl, - success: true, + await new Promise((resolve) => { + const processExitListener = (signal?: number | NodeJS.Signals) => () => { + startProcess.kill(signal); + resolve(); }; - } finally { - if (childProcess) { - childProcess.kill(); - } - } + process.on('exit', processExitListener); + process.on('SIGTERM', processExitListener); + process.on('SIGINT', processExitListener); + process.on('SIGQUIT', processExitListener); + }); } /* @@ -52,7 +46,7 @@ export async function runCliStart( workspaceRoot: string, projectRoot: string, options: ReactNativeStartOptions -): Promise { +): Promise { const result = await isPackagerRunning(options.port); if (result === 'running') { logger.info('JS server already running.'); @@ -63,7 +57,7 @@ export async function runCliStart( logger.info('Starting JS server...'); try { - await startAsync(workspaceRoot, projectRoot, options); + return await startAsync(workspaceRoot, projectRoot, options); } catch (error) { logger.error( `Failed to start the packager server. Error details: ${error.message}` @@ -77,24 +71,34 @@ function startAsync( workspaceRoot: string, projectRoot: string, options: ReactNativeStartOptions -): Promise { - return new Promise((resolve, reject) => { - childProcess = fork( - join(workspaceRoot, './node_modules/react-native/cli.js'), +): Promise { + return new Promise((resolve, reject) => { + const childProcess = fork( + require.resolve('react-native/cli.js'), ['start', ...createStartOptions(options)], - { cwd: join(workspaceRoot, projectRoot), env: process.env } + { + cwd: pathResolve(workspaceRoot, projectRoot), + env: process.env, + stdio: ['inherit', 'pipe', 'pipe', 'ipc'], + } ); - // Ensure the child process is killed when the parent exits - process.on('exit', () => childProcess.kill()); - process.on('SIGTERM', () => childProcess.kill()); + childProcess.stdout.on('data', (data) => { + process.stdout.write(data); + if (data.toString().includes('Packager is ready')) { + resolve(childProcess); + } + }); + childProcess.stderr.on('data', (data) => { + process.stderr.write(data); + }); childProcess.on('error', (err) => { reject(err); }); childProcess.on('exit', (code) => { if (code === 0) { - resolve(code); + resolve(childProcess); } else { reject(code); } diff --git a/packages/react-native/src/generators/application/application.ts b/packages/react-native/src/generators/application/application.ts index 2381112bae027e..fa5f0224cc71cd 100644 --- a/packages/react-native/src/generators/application/application.ts +++ b/packages/react-native/src/generators/application/application.ts @@ -7,7 +7,6 @@ import { Tree, } from '@nx/devkit'; -import { runPodInstall } from '../../utils/pod-install-task'; import { runSymlink } from '../../utils/symlink-task'; import { addLinting } from '../../utils/add-linting'; import { addJest } from '../../utils/add-jest'; @@ -48,10 +47,6 @@ export async function reactNativeApplicationGenerator( ); const detoxTask = await addDetox(host, options); const symlinkTask = runSymlink(host.root, options.appProjectRoot); - const podInstallTask = runPodInstall( - joinPathFragments(host.root, options.iosProjectRoot), - options.install - ); const chmodTaskGradlew = chmodAndroidGradlewFilesTask( joinPathFragments(host.root, options.androidProjectRoot) ); @@ -66,7 +61,6 @@ export async function reactNativeApplicationGenerator( jestTask, detoxTask, symlinkTask, - podInstallTask, chmodTaskGradlew ); } diff --git a/packages/react-native/src/generators/application/files/app/.ruby-version b/packages/react-native/src/generators/application/files/app/.ruby-version deleted file mode 100644 index 49cdd668e1c82b..00000000000000 --- a/packages/react-native/src/generators/application/files/app/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.7.6 diff --git a/packages/react-native/src/generators/application/files/app/Gemfile.template b/packages/react-native/src/generators/application/files/app/Gemfile.template index 567e59805c4a73..1fa2c2e1abdee6 100644 --- a/packages/react-native/src/generators/application/files/app/Gemfile.template +++ b/packages/react-native/src/generators/application/files/app/Gemfile.template @@ -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 File.read(File.join(__dir__, '.ruby-version')).strip +ruby ">= 2.6.10" -gem 'cocoapods', '~> 1.11', '>= 1.11.3' +gem 'cocoapods', '~> 1.12' diff --git a/packages/react-native/src/generators/application/files/app/android/app/build.gradle.template b/packages/react-native/src/generators/application/files/app/android/app/build.gradle.template index 8ce7b1ab639de5..1fc5a2aeb56438 100644 --- a/packages/react-native/src/generators/application/files/app/android/app/build.gradle.template +++ b/packages/react-native/src/generators/application/files/app/android/app/build.gradle.template @@ -1,8 +1,6 @@ apply plugin: "com.android.application" apply plugin: "com.facebook.react" -import com.android.build.OutputFile - /** * This is the configuration block to customize your React Native Android app. * By default you don't need to apply any configuration, just uncomment the lines you need. @@ -13,8 +11,8 @@ react { // root = file("../") // The folder where the react-native NPM package is. Default is ../node_modules/react-native // reactNativeDir = file("../node_modules/react-native") - // The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen - // codegenDir = file("../node_modules/react-native-codegen") + // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen + // codegenDir = file("../node_modules/@react-native/codegen") // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js // cliFile = file("../node_modules/react-native/cli.js") @@ -53,14 +51,6 @@ react { entryFile = file("../../<%= entryFile %>") } -/** - * Set this to true to create four separate APKs instead of one, - * one for each native architecture. This is useful if you don't - * use App Bundles (https://developer.android.com/guide/app-bundle/) - * and want to have separate APKs to upload to the Play Store. - */ -def enableSeparateBuildPerCPUArchitecture = false - /** * Set this to true to Run Proguard on Release builds to minify the Java bytecode. */ @@ -79,16 +69,6 @@ def enableProguardInReleaseBuilds = false */ def jscFlavor = 'org.webkit:android-jsc:+' -/** - * Private function to get the list of Native Architectures you want to build. - * This reads the value from reactNativeArchitectures in your gradle.properties - * file and works together with the --active-arch-only flag of react-native run-android. - */ -def reactNativeArchitectures() { - def value = project.getProperties().get("reactNativeArchitectures") - return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] -} - android { ndkVersion rootProject.ext.ndkVersion @@ -106,15 +86,6 @@ android { testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' <% } %> } - - splits { - abi { - reset() - enable enableSeparateBuildPerCPUArchitecture - universalApk false // If true, also generate a universal APK - include (*reactNativeArchitectures()) - } - } signingConfigs { debug { storeFile file('debug.keystore') @@ -138,22 +109,6 @@ android { <% } %> } } - - // applicationVariants are e.g. debug, release - applicationVariants.all { variant -> - variant.outputs.each { output -> - // For each separate APK per architecture, set a unique version code as described here: - // https://developer.android.com/studio/build/configure-apk-splits.html - // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc. - def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] - def abi = output.getFilter(OutputFile.ABI) - if (abi != null) { // null for the universal-debug, universal-release variants - output.versionCodeOverride = - defaultConfig.versionCode * 1000 + versionCodes.get(abi) - } - - } - } } dependencies { @@ -164,8 +119,6 @@ dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") - implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0") - debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { exclude group:'com.squareup.okhttp3', module:'okhttp' diff --git a/packages/react-native/src/generators/application/files/app/android/app/src/main/java/com/__lowerCaseName__/MainActivity.java.template b/packages/react-native/src/generators/application/files/app/android/app/src/main/java/com/__lowerCaseName__/MainActivity.java.template index 629bff52ba19fc..981e6233377b76 100644 --- a/packages/react-native/src/generators/application/files/app/android/app/src/main/java/com/__lowerCaseName__/MainActivity.java.template +++ b/packages/react-native/src/generators/application/files/app/android/app/src/main/java/com/__lowerCaseName__/MainActivity.java.template @@ -1,4 +1,4 @@ -package com.<%= lowerCaseName %>; +package com.<%= className %>; import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivityDelegate; @@ -27,9 +27,6 @@ public class MainActivity extends ReactActivity { this, getMainComponentName(), // If you opted-in for the New Architecture, we enable the Fabric Renderer. - DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled - // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18). - DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled - ); + DefaultNewArchitectureEntryPoint.getFabricEnabled()); } } diff --git a/packages/react-native/src/generators/application/files/app/android/app/src/main/res/drawable/rn_edit_text_material.xml b/packages/react-native/src/generators/application/files/app/android/app/src/main/res/drawable/rn_edit_text_material.xml index f35d9962026a85..73b37e4d9963e2 100644 --- a/packages/react-native/src/generators/application/files/app/android/app/src/main/res/drawable/rn_edit_text_material.xml +++ b/packages/react-native/src/generators/application/files/app/android/app/src/main/res/drawable/rn_edit_text_material.xml @@ -20,7 +20,7 @@ android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"> -