Closed vladp closed 4 years ago
cc @grabbou
AFAICT the change was intentional, to fix a lot of other custom structure issues. Now, if the RN app is nested in a directory, we expect users to call CLI from that nested directory, and we don't care whether the node_modules/react-native are hoisted or not. Please share your repo structure and the way you use it, so we can advise.
Sure. appreciate in advance your guidance.
I am showing quite a bit of complexity below (essentially most of our front-end project tree).
You will see there android app (under a),
web applications (aa1a) and (ua1c) that are built in React Native Web.
Then you will see rn.common which is where our shared React-Native code is. It is shared by Android app (that has just 1 activity with React native), and by all of the web apps.
There is a lot of co-dependency across all of that stuff and reliance on the specific directory structure we have now. Which is also why configuring React native root when building android app was essential for us.
FRONTEND-OF-MYAPP
|-- a (* this is where android app code resides. Android app has just 1 activity that uses RN, RN's js code is rn.common *)
| `-- u1b
| |-- LICENSE.md
| |-- README.md
| |-- app
| | |-- BUCK
| | |-- build.gradle
| | |-- build_defs.bzl
| | |-- config
| | | |-- gradle_cfg
| | | | |-- build.gradle
| | | | |-- jacoco.gradle
| | | | |-- quality.gradle
| | | | `-- versioning.gradle
| | | |-- signing
| | | | |-- readme.md
| | | | |-- release.keystore
| | | | `-- signing.properties
| | | `-- static_analysis
| | | |-- checkstyle
| | | | |-- checkstyle_rules.xml
| | | | `-- checkstyle_suppression_filter.xml
| | | |-- findbugs
| | | | `-- findbugs-exclusions.xml
| | | `-- pmd
| | | `-- pmd_rules.xml
| | |-- proguard-rules.pro
| | `-- src
| | |-- main
| | | |-- AndroidManifest.xml
| | | |-- assets
| | | | |-- fonts
| | | | |-- project.properties
| | | |-- java
| | | | `-- com
| | | `-- res
| | | |-- drawable
| | | |-- drawable-v24
| | | |-- layout
| | | |-- menu
| | | |-- values
| | | |-- values-w600dp
| | | |-- values-w820dp
| | | `-- xml
| | |-- qa
| | | `-- res
| | | |-- mipmap-hdpi
| | |-- release
| | | `-- java
| | | `-- com
| | |-- testHelpers
| | | |-- java
| | | | `-- com
| | | `-- resources
| | |-- unitTests
| | | `-- java
| | | `-- com
| | |-- unitTestsDebug
| | | `-- java
| | | `-- com
| | |-- unitTestsQa
| | | `-- java
| | | `-- com
| | `-- unitTestsRelease
| | `-- java
| | `-- com
| |-- art
| |-- build.gradle
| |-- config
| | `-- ide
| |-- gradle
| | `-- wrapper
| | `-- gradle-wrapper.properties
| |-- gradle.properties
| `-- settings.gradle
|-- rn.common (* contains code used by Android's RN activity, and by many screens in my WebApps that use React Native Web, see symlinks to rn.common in aa1a and ua1c *)
| |-- index.android.js
| |-- package.json
| |-- react-native.config.js
| |-- src
| | |-- js.app
| | | |-- img
| | | | |-- ic_local_library_black_48dp.png
| | | | `-- ic_menu_black_48dp.png
| | | |-- mdk
| | | |-- mybusiness.components
| | | | |-- nonui
| | | | `-- rnui
| | | `-- mybusiness.main
| |-- u1b__rn.code-workspace
`-- rnweb
|-- aa1a
| |-- app.src
| | |-- components
| | |-- containers
| | |-- reducers
| | |-- store
| | `-- styles
| |-- csr-cra
| | |-- README.md
| | |-- aa1a-csr-cra.code-workspace
| | |-- config-overrides.js
| | |-- package.json
| | |-- public
| | |-- src
| | | |-- App.css
| | | |-- App.js
| | | |-- App.test.js
| | | |-- app.src -> ../../app.src/
| | | |-- index.css
| | | |-- index.js
| | | |-- js.app -> ../../../../rn.common/src/js.app/
| | | |-- logo.svg
| | | |-- registerServiceWorker.js
| | | |-- serviceWorker.js
| | | `-- wc.src -> ../../../web.common/wc.src/
| |-- replace_file_link_with_dir_link.cmd
|-- ua1c
| |-- app.src
| | `-- readme.txt
| |-- create_sym_links.sh
| |-- csr-cra
| | |-- config-overrides.js
| | |-- dev-launch-win.cmd
| | |-- dev_build_and_deploy.cmd
| | |-- dev_build_and_deploy.sh
| | |-- ide-set.sh
| | |-- package.json
| | |-- public
| | |-- src
| | | |-- App.css
| | | |-- App.js
| | | |-- App.test.js
| | | |-- Landing.js
| | | |-- app.src -> ../../app.src/
| | | |-- index.css
| | | |-- index.js
| | | |-- js.app -> ../../../../rn.common/src/js.app/
| | | |-- logo.svg
| | | |-- registerServiceWorker.js
| | | |-- serviceWorker.js
| | | `-- wc.src -> ../../../web.common/wc.src/
| | `-- ua1c-csr-csra.code-workspace
`-- web.common
`-- wc.src
|-- domain
| `-- components
| |-- ecommerce
| `-- venuesignup
|-- nonui
| `-- readme.txt
`-- ui
`-- readme.txt
Thanks for reporting this over.
The problem here is that you don't have package.json
anywhere in the Android app or at the root of your project.
The CLI automatically resolves the "root" of your project by looking for the closest package.json
in the directory structure. The "root" option you're referring to in the Gradle configuration is something different and that's what React Native uses for bundling resources.
I am surprised that this setup is working for you. Autolinking is looking for dependencies to link from a "package.json" and there's clearly no "package.json" with modules to link in your setup.
As a result of such directory structure, the two following problems will happen:
CLI will be unable to resolve a "package.json" going up the directory tree, starting from "u1b/android", where it's being called while you run your app.
As a result, CLI will not be able to find "react-native" dependency using "require.resolve" mechanism either. "require.resolve" goes up the directory structure as well (which is why we have ended up using the same heuristics - staying compliant with what Node is already doing). I believe "react-native" resides in "../../rn.common/node_modules", starting from "a/u1b", so it's not going to be available.
The solution requires doing few tweaks to the directory structure you have set up.
The most elegant way would be to set up a Yarn workspaces project for this. In order to get this working, you would need to make sure that each project has a valid package.json
inside, even if it's empty.
Your a/u1b
should have a package.json
and define a dependency on react-native
, because it's depending on the React Native and actually, building it during runtime using the CLI and Gradle. You wouldn't need to this if you were just consuming a precompiled "RN.Common" archive, not having any build step at all.
You also need to explicitly list down all React Native packages that you want to link to your Android/iOS app in such package.json
as well. CLI looks for dependencies to link in the closest package.json
, when you build your project.
When running yarn
in such a project, all "node_modules" from each application would be hoisted to the root of the project. In your case, that's "FRONTEND-OF-MY-APP/node_modules". Thanks to that, you would end up with just a single copy of "react-native" at the root, despite all your packages requiring a dependency on it.
It will also automatically support setting cross-links between your projects. Just set your packages to depend on each other and Yarn will take care of it.
For example, our CLI uses this and packages are automatically symlinked when needed. It is also the setup that we recommend for "monorepositories" and library developers. We are most likely to keep supporting it in the foreseeable future.
One additional note regarding my previous comment:
I believe you have designed this folder structure to re-use code between mobile and web, hence "rn.common" folder with "common" code.
However, taking a closer look at its contents, it's not "common". It contains "index.android.js" (entry point for an Android mobile app) and many other things. So at the end of the day, it combines two things: React Native code for Android mobile application and some React / JavaScript code that you may share on the Web.
In my opinion, the React Native code responsible for Android / iOS mobile application should reside under "a/u1b" where the complementary native code is located. That way, you can write some mobile-specific code as well without polluting the common folder.
By creating a package.json
in that folder, this will be both possible and compatible with what CLI expects.
@grabbou thank you for the follow ups. Let me ask this, -- is it possible, via configuration, to disable autolinking performed by the CLI?
Our Android app is a 'hybrid' (there is only one activity using RN), and we already specify the packages that must be 'loaded' by the RN Android runtime (there is only 1, vector-icons). The rest of the packages in rn.common/package.json do not need to be loaded by RN Android runtime, and are just bundled in. Plus, we are very happpy to continue to specify manually all the packages we want loaded, as we do today. So, essentially, autolinking feature is not essentiall at all for us.
Given that you spend effort offering explanation on why we should restructure our repo (thank you for that), let me offer some replies (although I am not sure they are particuallary convicing, I hope it gives bit more background/picture to others as well).
Overall, once in a while we think of moving our 'common/reusable' code into some form of custom node modules, then setting up custom NPM-like repo internally and pulling it from there. Or learning other tooling options around lerna/etc. At this stage our resources/delivery priorities simply cannot afford the complexity+time involved.
The CLI automatically resolves the "root" of your project by looking for the closest package.json
It appears, that the change was made, exactly in this feature. Now there is no way to tell CLI were my root project is (root meaning code+node_modules).
Perhaps, you were thinking to model it after how webpack looks up node_modules. I think this is a familiar model for js/webpack devs, so it can be a reasonable idea.
But in many cases, RN is just small piece of the overall edge-device/front-end code and the overall structure is dictated by other 'opinioned/less opinioned' toolchains.
So overall, I would still advocate that autolinking or any other RN build toolchain feature allows for flexibility of defining where files can reside, and were roots of RN can reside.
In my opinion, the React Native code responsible for Android / iOS mobile application should reside under "a/u1b" where the complementary native code is located.
Well that's was not the intent. We are not that RN-centric. We did not want to merge front-end apps under one root, just because they happen to rely on RN in a couple of screens.
We would put 2nd android app under a, but not under a/u1b ios apps would go under i, (eg i/a2a i/a1b and so on ... ) windows apps under w, framebuffer front ends for microntrollers, under b Some do not rely on RN at all.
So a/u1b means 'AndroidApp-endusers-Domain1B' i/a1b -- means IosApp-administrators-Domain1B And so on.
As a philosophy, in a way, we structure our monorepo on combination of 'BusinessFunction+BusinessDomain', rather than on 'ProgrammingLanguage+ProgrammingLibrary+BussinessFunction'
We also have operations domains (devops, and so on, they are structured same way, but start with devops as this a operations domain).
WRT " However, taking a closer look at its contents, it's not "common". It contains "index.android.js" (entry point for an Android mobile app) and many other things. So at the end of the day, it combines two things: React Native code for Android mobile application and some React / JavaScript code that you may share on the Web. "
That's true, I tried my best to move android.index.js (and 2 other files) out of rn.common into its own. However Metro bundler insists that I have index.android.js and the files it referrers to underneath its dir (and not above or in siblings dir). Metro, allowed that in previous versions, but they removed that capabilty too. I entered an issue for it a couple of months ago, unresolved sofar https://github.com/facebook/metro/issues/444#issuecomment-542579255
But even if metro would have fixed the above issue, moving index.android.js out of rn.common would not have helped the new CLI to find rn.common.
Not sure if this useful, but here is (sanitizied) output of
npx.cmd --quiet react-native config
When it is executed from rn.common (this is what CLI was receiveing, when it was respecting my root setting, with the old code
cmdProcess = Runtime.getRuntime().exec(command, null, root)
):
{
"root": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common",
"reactNativePath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native",
"dependencies": {
"react-native-vector-icons": {
"root": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons",
"name": "react-native-vector-icons",
"platforms": {
"ios": {
"sourceDir": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons",
"folder": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons",
"pbxprojPath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\RNVectorIcons.xcodeproj\\project.pbxproj",
"podfile": null,
"podspecPath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\RNVectorIcons.podspec",
"projectPath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\RNVectorIcons.xcodeproj",
"projectName": "RNVectorIcons.xcodeproj",
"libraryFolder": "Libraries",
"sharedLibraries": [],
"plist": [],
"scriptPhases": []
},
"android": {
"sourceDir": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\android",
"folder": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons",
"packageImportPath": "import com.oblador.vectoricons.VectorIconsPackage;",
"packageInstance": "new VectorIconsPackage()"
}
},
"assets": [
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\AntDesign.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\Entypo.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\EvilIcons.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\Feather.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\FontAwesome.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\FontAwesome5_Brands.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\FontAwesome5_Regular.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\FontAwesome5_Solid.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\Fontisto.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\Foundation.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\Ionicons.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\MaterialCommunityIcons.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\MaterialIcons.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\Octicons.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\SimpleLineIcons.ttf",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\node_modules\\react-native-vector-icons\\Fonts\\Zocial.ttf"
],
"hooks": {},
"params": []
}
},
"commands": [
{
"name": "log-ios",
"description": "starts iOS device syslog tail"
},
{
"name": "run-ios",
"description": "builds your app and starts it on iOS simulator",
"examples": [
{
"desc": "Run on a different simulator, e.g. iPhone 5",
"cmd": "react-native run-ios --simulator \"iPhone 5\""
},
{
"desc": "Pass a non-standard location of iOS directory",
"cmd": "react-native run-ios --project-path \"./app/ios\""
},
{
"desc": "Run on a connected device, e.g. Max's iPhone",
"cmd": "react-native run-ios --device \"Max's iPhone\""
},
{
"desc": "Run on the AppleTV simulator",
"cmd": "react-native run-ios --simulator \"Apple TV\" --scheme \"helloworld-tvOS\""
}
],
"options": [
{
"name": "--simulator [string]",
"description": "Explicitly set simulator to use. Optionally include iOS version betweenparenthesis at the end to match an exact version: \"iPhone 6 (10.0)\"",
"default": "iPhone X"
},
{
"name": "--configuration [string]",
"description": "Explicitly set the scheme configuration to use",
"default": "Debug"
},
{
"name": "--scheme [string]",
"description": "Explicitly set Xcode scheme to use"
},
{
"name": "--project-path [string]",
"description": "Path relative to project root where the Xcode project (.xcodeproj) lives.",
"default": "ios"
},
{
"name": "--device [string]",
"description": "Explicitly set device to use by name. The value is not required if you have a single device connected."
},
{
"name": "--udid [string]",
"description": "Explicitly set device to use by udid"
},
{
"name": "--no-packager",
"description": "Do not launch packager while building"
},
{
"name": "--verbose",
"description": "Do not use xcpretty even if installed"
},
{
"name": "--port [number]",
"default": 8081
},
{
"name": "--terminal [string]",
"description": "Launches the Metro Bundler in a new window using the specified terminal path."
}
]
},
{
"name": "log-android",
"description": "starts logkitty"
},
{
"name": "run-android",
"description": "builds your app and starts it on a connected Android emulator or device",
"options": [
{
"name": "--root [string]",
"description": "Override the root directory for the android build (which contains the android directory)",
"default": ""
},
{
"name": "--variant [string]",
"description": "Specify your app's build variant",
"default": "debug"
},
{
"name": "--appFolder [string]",
"description": "Specify a different application folder name for the android source. If not, we assume is \"app\"",
"default": "app"
},
{
"name": "--appId [string]",
"description": "Specify an applicationId to launch after build.",
"default": ""
},
{
"name": "--appIdSuffix [string]",
"description": "Specify an applicationIdSuffix to launch after build.",
"default": ""
},
{
"name": "--main-activity [string]",
"description": "Name of the activity to start",
"default": "MainActivity"
},
{
"name": "--deviceId [string]",
"description": "builds your app and starts it on a specific device/simulator with the given device id (listed by running \"adb devices\" on the command line)."
},
{
"name": "--no-packager",
"description": "Do not launch packager while building"
},
{
"name": "--port [number]",
"default": 8081
},
{
"name": "--terminal [string]",
"description": "Launches the Metro Bundler in a new window using the specified terminal path."
},
{
"name": "--tasks [list]",
"description": "Run custom Gradle tasks. By default it's \"installDebug\""
},
{
"name": "--no-jetifier",
"description": "Do not run \"jetifier\" – the AndroidX transition tool. By default it runs before Gradle to ease working with libraries that don't support AndroidX yet. See more at: https://www.npmjs.com/package/jetifier.",
"default": false
}
]
}
],
"assets": [
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\src\\js.app\\img\\ic_local_library_black_48dp.png",
"C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\src\\js.app\\img\\ic_menu_black_48dp.png"
],
"platforms": {
"ios": {},
"android": {}
},
"haste": {
"providesModuleNodeModules": [
"react-native"
],
"platforms": [
"ios",
"android"
]
},
"project": {
"ios": null,
"android": {
"sourceDir": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\a\\u1b\\app\\src",
"isFlat": false,
"folder": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common",
"stringsPath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\a\\u1b\\app\\src\\src\\main\\res\\values\\strings.xml",
"manifestPath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\a\\u1b\\app\\src\\debugAndQa\\AndroidManifest.xml",
"buildGradlePath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\a\\u1b\\app\\src\\build.gradle",
"settingsGradlePath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\rn.common\\android\\settings.gradle",
"assetsPath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\a\\u1b\\app\\src\\src\\main\\assets",
"mainFilePath": "C:\\Users\\v\\home\\devel\\myrepo\\FRONTEND\\a\\u1b\\app\\src\\src\\main\\java\\com\\u1b\\MainApplication.java",
"packageName": "com.u1b"
}
}
}
just wanted to check with @grabbou or @thymikee if they could think of a way forward/workaround, without requiring us to restructure our source repo.
@vladp I wonder if the change we cook here would help in your case? https://github.com/react-native-community/cli/pull/824
@thymikee I think if you will find a way to pass value of
app/build.android
project.ext.react.root
into line 155 of the npx command in
def cmdProcess
def npx = Os.isFamily(Os.FAMILY_WINDOWS) ? "npx.cmd" : "npx"
def command = "${npx} --quiet react-native config" //<--- line 155
def reactNativeConfigOutput = ""
then it will work.
Looking at you project structure, this patch should work in your case.
With the changes done there we'd run npx react-native config
directly from within the rn.common/
directory, which holds node_modules with CLI and react-native
. Even if you started to hoist the dependencies to the parent directory, it would still work because of Node resolution algorithm used by npx.
Am I missing something? Feel free to replace your native_modules.gradle
with the one that's there.
@thymikee I just tested your update on top of 0.61, and it works for us!. Thank you for this.
It seems that what you have done, is leveraged the fact that everybody in their
app/build.gradle
already had to specify where RN gradle is (and therefore where node_modules for RN is)
Then you assume that that's the directory with RN's node_modules, is the root of the RN project,
and that's where you now run npx react-native config
That works well, it makes sense, it allows us the flexibility to keep RN common code, in whatever directory structure we want, and, as 'icing on the cake' eliminates the need to re-specify the location of that directory like 3 additional times.
Reopening because of https://github.com/react-native-community/cli/pull/852. We need to find better solution
@grabbou I have a monorepo structure set up almost identical to the one you suggested earlier, but the RN CLI doesn't work properly in root. I don't want a react-native
package in root, and would like to instead force each sub-folder to specify the RN version in their package.json
. However, after doing this the CLI can't find run-android
as a command for some reason when running from root.
I checked and I'm sure that react-native
, along with all the other packages I need, are correctly hoisted up to root. The react-native
command even runs, but it doesn't think that run-android
is a valid sub-command. I'm currently running react-native run-android --root "./projectName"
. Is there any more configuration that is needed? To note, this works perfectly fine if I leave react-native
in the root package.json
.
Looking through the global .bin
for react-native
it appears to kick it to my node_modules/@react-native-community/cli
package after going through the react-native
one. There is also node_modules/@react-native-community/cli-platform-android
which appears to have the commands I am missing, but I'm not sure how the main cli links to it.
Structure just to be clear:
package.json
-> project1
package.json
-> android
-> ios
-> project2
package.json
-> android
-> ios
where the sub-projects have essentially this as their package.json
{
...
"dependencies": {
"react-native": "0.61.5"
...
}
...
}
and root has ideally nothing in its dependencies (or very little).
Also please feel free to send me to another issue if this isn't a good place to ask.
why did you closed this issue
@lylest because we believe it was fixed by #1057 available in latest CLI version, which lets you get rid of root
from Gradle config.
@thymikee Please re-open this issue. The problem I reported is not resolved.
I am getting
'[node, -e, console.log(require('react-native/cli').bin);]' in directory 'C:\Users\v\home\devel\myrepo\FRONTEND\a\u1b' command failed.
React native 0.62. using most recent CLI release 4.7.0
when executing the build from android studio
or when running gradlew task
In the u1b , the edirectory where I have my android project (see my directory structure fully described October 16, 2019 comment)
FRONTEND-OF-MYAPP
|-- a (* this is where android app code resides. Android app has just 1 activity that uses RN, RN's js code is rn.common *)
| `-- u1b
The problem still seems to be same (using 4.7.0 release of cli. Tried both on Windows and Linux). The cli is trying to execute java script commands in my Android app directory (u1b), and not in the correct directory which is rn.common
My settings.gradle is the same as when reported the issue 6 months ago
rootProject.name = 'u1b'
def myRnAppRootDir_abs="${rootDir}/../../rn.common"
def myRnAppRootDir_rel="../../rn.common"
apply from: file("${myRnAppRootDir_abs}/node_modules/@react-native-community/cli-platform-android/native_modules.gradle")
applyNativeModulesSettingsGradle(settings,myRnAppRootDir_rel)
...
Same build.gradle:
plugins {
id 'com.android.application'
id("com.github.triplet.play") version "2.6.1"
}
import com.android.build.OutputFile
def myRnAppRootDir_abs="${rootDir}/../../rn.common"
def myRnAppRootDir_rel="../../rn.common"
def myMinSDKVer=21
apply from: 'config/gradle_cfg/quality.gradle'
project.ext.react = [
entryFile: "index.android.js",
bundleInDebug: false,
bundleInRelease: true,
bundleCommand: "ram-bundle",
enableHermes: false, // clean and rebuild if changing
root: "${myRnAppRootDir_abs}"
]
apply from: "${myRnAppRootDir_abs}/node_modules/react-native/react.gradle"
apply from: "${myRnAppRootDir_abs}/node_modules/react-native-vector-icons/fonts.gradle"
...
apply from: file("${myRnAppRootDir_abs}/node_modules/@react-native-community/cli-platform-android/native_modules.gradle");
applyNativeModulesAppBuildGradle(project,"${myRnAppRootDir_rel}")
NODE_MODULES environment variable is not set
v12.16.1
The problem, clearly the same as before
When settings.gradle invokes
applyNativeModulesSettingsGradle(settings)
CLI's node_modules/@react-native-community/cli-platform-android/native_modules.gradle
fails to figure out where my JS directory is (rn.common) -- because that capability was removed with CLI release in rn 0.61.
To confirm that this is same problem, I modified native_modules.gradle and applied the same solution as @thymikee created before (getting the JS directory from the path of nativ_modules.gradle)
// find current directory and set is as the one to use for subsequent autolinking machinery
def jsAppDir = buildscript.sourceFile.toString().split("node_modules/@react-native-community/cli-platform-android/native_modules.gradle")[0]
def projectRoot = (jsAppDir != null)? new File(jsAppDir) : rootProject.projectDir;
def autoModules = new ReactNativeModules(logger,projectRoot)
That allowed to build to pass the above mentioned error... But without the above change to CLI code, I simply do not know how to get this to even start the build.
It is still a problem I am just with my project for a week now
still happen in 0.71.3
Environment
System: OS: Windows 10 CPU: (8) x64 Intel(R) Core(TM) i Memory: 15.44 GB Binaries: Node: 12.10.0 - C:\Program Files\nodejs\node.EXE Yarn: 1.19.1 - C:\Users\v\AppData\Roaming\npm\yarn.CMD npm: 6.12.0 - C:\Program Files\nodejs\npm.CMD npmPackages: react: 16.9.0 => 16.9.0 react-native: ^0.61 => 0.61.2
Description
my directory structure is andrapp\ <-- has android ./app , gradlew and so on rn.common\ <-- has package.json index.android.js and ./node_modules
in react-native 60.6 I was able to specify the React native root (in app/build.gradle)
And cli was able to correctly invoke
npx.cmd --quiet react-native config
from within rn.common directory
However since this change https://github.com/react-native-community/cli/commit/5724d29dc979a4b645c620109348a1e5c8c74d03#diff-375026a0607eb034a6fc70cca7d74689
native_modules.gradle Now invokes npx in 'default' directly, not in React's project root. Which causes
npx.cmd --quiet react-native config
to complain withWhich, then, causes JSON parsing error in native_modules.js
Here is code change in native_modules.js that causes the error on Android
// old code, that was working cmdProcess = Runtime.getRuntime().exec(command, null, root)
// new code that does not work cmdProcess = Runtime.getRuntime().exec(command)
From the design/documentation perspective, it seems that the whole infrastructure for getReactNativeProjectRoot() have been removed, and no alternative/migration documentation has been suggested.
Note also, that react-native 0.61 project template, continues to assert that configuring custom root (where package.json) resides, by specifying root in project.ext.react (in app/build.gradle) -- is still a valid and supported option
https://github.com/facebook/react-native/blob/master/template/android/app/build.gradle