react-native-community/cli

Change default location of iOS and Android folder

hamidhadi opened this issue ยท 17 comments

(I asked this on StackOverflow but nobody answered so I decided to report that here)

Environment

System:
    OS: macOS 10.15.1
    CPU: (4) x64 Intel(R) Core(TM) i5-4278U CPU @ 2.60GHz
    Memory: 20.93 MB / 8.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.7.0 - /Volumes/JETDRIVE/.nvm/versions/node/v12.7.0/bin/node
    Yarn: 1.19.0 - /usr/local/bin/yarn
    npm: 6.10.0 - /Volumes/JETDRIVE/.nvm/versions/node/v12.7.0/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.8.4 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 23, 28, 29
      Build Tools: 23.0.1, 28.0.3, 29.0.1
      System Images: android-29 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5900203
    Xcode: 11.3/11C29 - /usr/bin/xcodebuild
  Languages:
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.11.0 => 16.11.0 
    react-native: 0.62.0 => 0.62.0 
  npmGlobalPackages:
    *react-native*: Not Found

Description

According to the react-native CLI documentation we can specify custom configuration based on each platform for RN CLI. I want to change the default location of each platform folders so I added my custom react-native.config.js to the root of the project which you can find that here:

module.exports = {
  project: {
    ios: {
      project: './example/ios/example.xcworkspace',
    },
    android: {
      sourceDir: './example/android/',
    },
  },
};

If I run react-native config in the root folder, I can see the correct configuration:

{
...
  "project": {
    "ios": {
      "sourceDir": "path-to-project-directory/example/ios",
      "folder": "path-to-project-directory",
      "pbxprojPath": "path-to-project-directory/example/ios/example.xcworkspace/project.pbxproj",
      "podfile": "path-to-project-directory/example/ios/Podfile",
      "podspecPath": null,
      "projectPath": "path-to-project-directory/example/ios/example.xcworkspace",
      "projectName": "example.xcworkspace",
      "libraryFolder": "Libraries",
      "sharedLibraries": [],
      "plist": [],
      "scriptPhases": []
    },
    "android": {
      "sourceDir": "path-to-project-directory/example/android/",
      "isFlat": true,
      "folder": "path-to-project-directory",
      "stringsPath": "path-to-project-directory/example/android/app/src/main/res/values/strings.xml",
      "manifestPath": "path-to-project-directory/example/android/app/src/main/AndroidManifest.xml",
      "buildGradlePath": "path-to-project-directory/example/android/build.gradle",
      "settingsGradlePath": "path-to-project-directory/example/android/settings.gradle",
      "assetsPath": "path-to-project-directory/example/android/app/src/main/assets",
      "mainFilePath": "path-to-project-directory/example/android/app/src/main/java/com/example/MainApplication.java",
      "packageName": "com.example",
      "packageFolder": "com/example",
      "appName": "app"
    }
  }
}

The problem is whenever I run react-native run-ios I get this error:

error iOS project folder not found. Are you sure this is a React Native project?. Run CLI with --verbose flag for more details.

NOTE: I installed all the dependencies properly. Here is the result of the react-native --v command:

react-native-cli: 2.0.1
react-native: 0.62.0

Reproducible Demo

  1. Create a RN project via react-native init
  2. Create a subfolder in the project and move ios and android folders there
  3. Create a react-native.config.js in the root directory and export project configuration as I provided in this issue(You can find in the Description section).
  4. Try to run the project via react-native run-ios or react-native run-android

I'm having the same issue on iOS. Got it working by specifying the project-path: react-native run-ios --project-path example/ios. But I feel this shouldn't be needed?

module.exports = {
  project: {
    android: {
      sourceDir: './example/android',
    },
    ios: {
      project: './example/ios/example.xcodeproj',
    },
  },
};

Looking at the code it looks like react-native.config.js is being ignored for iOS. The script simply looks for project/workspace in the root or --project-path.

const xcodeProject = findXcodeProject(fs.readdirSync('.'));

You can find full source code at TheWidlarzGroup/react-native-video#2005

Oh we should fix that. Would you like to contribute @jenshandersson? cc @grabbou

Thanks @jenshandersson ๐Ÿ‘
What about Android? ๐Ÿค”
It seems Android has the same issue. It gets AppFolder from args

@hamidhadi Android works fine for me. I think the args come from the react-native.config.js in this case.

const passedOptions = this.opts();

@jenshandersson Strange! I have this issue with Android as well!

Any updates on this bug? I've searched everywhere about how to not have to copy/paste my project into the "android" folder and instead tell the react-native module to look into a different directory instead. I also tried the same approach as the author and ran into the exact same error hmm..

the same error in android for me
android studio sync error,

same issue on android, any solution?

still same on android

hi guy, is there a solution?

same issue

same issue on ios

Steps to run the app from custom dir:

Imagine you have file structure like below:

image

Then you have to take those steps to have working iOS and Android Apps:

  • specify custom sourceDir in react-native.config.js:
module.exports = {
  project: {
    ios: {
      sourceDir: 'example',
    },
    android: {
      sourceDir: 'example/android/',
    },
  },
};

Adjust paths for node_modules like so:

iOS:

  • in Podfile change require_relative:
+ require_relative '../../node_modules/react-native/scripts/react_native_pods'
- require_relative '../node_modules/react-native/scripts/react_native_pods'
+ require_relative '../../node_modules/@react-native-community/cli-platform-ios/native_modules'
- require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
  • change Bundle React Native code and images shell script:
- 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";
+ 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";
  • change "Start Packager" shell script:
- echo "export RCT_METRO_PORT=${RCT_METRO_PORT}" > "${SRCROOT}/../../node_modules/react-native/scripts/.packager.env"
+ echo "export RCT_METRO_PORT=${RCT_METRO_PORT}" > "${SRCROOT}/../node_modules/react-native/scripts/.packager.env"
// ...
- open "$SRCROOT/../node_modules/react-native/scripts/launchPackager.command" || echo "Can't start packager automatically"
+ open "$SRCROOT/../../node_modules/react-native/scripts/launchPackager.command" || echo "Can't start packager automatically"

(remember to run bundle exec pod install command when you're done ๐Ÿ˜‰ )

Android:

  • in settings.gradle file:
- apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
- includeBuild('../node_modules/react-native-gradle-plugin')
+ apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
+ includeBuild('../../node_modules/react-native-gradle-plugin')
  • in app/build.grade:
project.ext.react = [
    enableHermes: true,  // clean and rebuild if changing
+    cliPath: "../../../node_modules/react-native/local-cli/cli.js",
]
- apply from: "../../node_modules/react-native/react.gradle"
+ apply from: "../../../node_modules/react-native/react.gradle"
// ...
- apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+ apply from: file("../../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
  • in build.grade:
repositories {
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
-            url("$rootDir/../node_modules/react-native/android")
+            url("$rootDir/../../node_modules/react-native/android")
        }
        maven {
            // Android JSC is installed from npm
-           url("$rootDir/../node_modules/jsc-android/dist")
+           url("$rootDir/../../node_modules/jsc-android/dist")
        }

Similar adjustments have to be made for new architecture blocks in mentioned files.

There hasn't been any activity on this issue in the past 3 months, so it has been marked as stale and it will be closed automatically if no further activity occurs in the next 7 days.