On iOS, you need to set PROJECT_ROOT in order to make CLI work in a monorepo. On Android, same set of configuration is required.
PROJECT_ROOT on iOS because it's not needed anymore
related to https://github.com/react-native-community/cli/issues/865 https://github.com/react-native-community/cli/issues/656
this is my error when building
Error: Cannot find module '/app/packages/app/node_modules/react-native/cli.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:794:15)
at Function.Module._load (internal/modules/cjs/loader.js:687:27)
at Function.Module.runMain (internal/modules/cjs/loader.js:1025:10)
at internal/main/run_main_module.js:17:11 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
as it searches for react-native in the wron glocation
I've got this working like this
project.ext.react = [
entryFile: "index.js",
bundleInStaging: true,
devDisabledInStaging: true,
bundleInAlpha: true,
devDisabledInAlpha: true,
enableHermes: false, // clean and rebuild if changing
+ root: "../../../../"
]
modifying root path on app/build.gradle
but this raised another issue
error Invalid platform "android" selected.
info Available platforms are: "native". If you are trying to bundle for an out-of-tree platform, it may not be installed.
it only shows the android command inside react-native packages inside our monorepo (like here https://github.com/entria/entria-fullstack/tree/master/packages/app), but fails on root
what is the proper solution for this?
fixed android like this
project.ext.react = [
cliPath: "../../node_modules/react-native/cli.js",
]
ios also need this
export NODE_BINARY=node
export PROJECT_ROOT="$PROJECT_DIR/.."
../../../node_modules/react-native/scripts/react-native-xcode.sh
Yeah, in my experience, this is the major root cause for all of the monorepo issues that a lot of people are facing these days.
Any idea how we could plug into it? Setting dynamically variables?
this is a hard one, maybe a monorepo documentation guide could be good enough
fixed android like this
project.ext.react = [ cliPath: "../../node_modules/react-native/cli.js", ]
In my case it was
project.ext.react = [
...
entryFile: "index.js",
cliPath: "../node_modules/react-native/cli.js",
]
Because project structure is:
node_modules/
- react-native/
mobile/
- node_modules/
- index.js
shared/
web/
@sibelius, following up to my discussions https://github.com/react-native-community/cli/issues/656#issuecomment-601097688, we should be able to safely remove PROJECT_ROOT.
In theory, we always want it to be ios/.. and even if it ends up being deeper in the hierarchy, CLI knows what to do.
If you look at the details of the commit that introduced this change - https://github.com/facebook/react-native/commit/9ccde378b6e6379df61f9d968be6346ca6be7ead, I believe its assumptions are no longer true and we can get rid of it.
Waiting for Janic to get back to me whether this is right and I believe we can follow up with a PR. This particular change shouldn't require anything on the CLI side.
The ideal for me is this on iOS, regardless of your step
export NODE_BINARY=node
../../../node_modules/react-native/scripts/react-native-xcode.sh
As per Janic's comment, we're good to go with the suggested changes.
I will proceed with them soon and link a PR that is landing in React Native as a result.
Just filled in React Native PR - https://github.com/facebook/react-native/pull/28354. Appreciate your review and support in additional explanations :)
Did anyone got build working with hermes enabled in a monorepo?
I've got hermes to work by telling react where it's files are:
hermesCommand: "/mnt/c/Users/user/WebstormProjects/project/node_modules/hermes-engine/%OS-BIN%/hermes",
This solved the initial issue of not being able to build becasue hermes executable was not found, however with this fix in place build is still failing with:
internal/modules/cjs/loader.js:638
throw err;
^
Error: Cannot find module '/mnt/c/Users/user/WebstormProjects/project/packages/mobile/node_modules/react-native/scripts/compose-source-maps.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
at Function.Module._load (internal/modules/cjs/loader.js:562:25)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
> Task :app:bundleReleaseJsAndAssets FAILED
...because it is looking for node_modules folder in wrong location; the correct location is the same as in hermesCommand, /mnt/c/Users/user/WebstormProjects/project/node_modules.
Building works with enableHermes: false, so it only fails with hermes is enabled.
Any suggestion how to get around this?
My full react config from gradle:
project.ext.react = [
entryFile : "index.js",
enableHermes: true, // clean and rebuild if changing
hermesCommand: "/mnt/c/Users/user/WebstormProjects/project/node_modules/hermes-engine/%OS-BIN%/hermes",
cliPath : "../../node_modules/react-native/cli.js",
]
EDIT:
I figured out that one can also use relative path for hermesCommand, which is a bit different than cliPath. Seems like one has to point hermesCommand 2 levels higher in directory structure (when compared to cliPath):
hermesCommand: "../../../../node_modules/hermes-engine/%OS-BIN%/hermes",
EDIT2 / SOLUTION:
By digging through the source code I found that composeSourceMapsPath config key exists, so my whole react config looks like this:
project.ext.react = [
entryFile : "index.js",
enableHermes: true, // clean and rebuild if changing
hermesCommand: "../../../../node_modules/hermes-engine/%OS-BIN%/hermes",
composeSourceMapsPath: "../../node_modules/react-native/scripts/compose-source-maps.js",
cliPath : "../../node_modules/react-native/cli.js",
]
This got me pass the issue with compose-source-maps.js and I think files were successfully processed by hermes. However, there seems to still be an issue with code-push, since build fails with
Error: Cannot find module '/mnt/c/Users/user/WebstormProjects/project/packages/mobile/node_modules"/react-native-code-push/scripts/generateBundledResourcesHash.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
at Function.Module._load (internal/modules/cjs/loader.js:562:25)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
...so this time code-push is looking node_modules in wrong location. I think this issue is out of scope here, so I guess I should check Microsoft's github regarding this.
Following @tad3j answer, using react-native 0.63.2 I had to change hermesCommand.
hermesCommand: "../../../../node_modules/hermes-engine/%OS-BIN%/hermes",
Changed to:
hermesCommand: "../../../../node_modules/hermes-engine/%OS-BIN%/hermesc",
I still need to pass all other configuration, composeSourceMapsPath, cliPath and hermesCommand. Not passing composeSourceMapsPath was throwing a error.
My monorepo configuration is more or less like this, trying to not use nohoist at all.
- node_modules
- react-native
- packages
- app
- web
- any other shared package
My final build.gradle project.ext.react is the following:
project.ext.react = [
entryFile: "packages/app/index.js",
enableHermes: true, // clean and rebuild if changing,
hermesCommand: "../../../../node_modules/hermes-engine/%OS-BIN%/hermesc",
composeSourceMapsPath: "../../node_modules/react-native/scripts/compose-source-maps.js",
cliPath: "../../node_modules/react-native/cli.js",
]
Most helpful comment
Did anyone got build working with hermes enabled in a monorepo?
I've got hermes to work by telling react where it's files are:
hermesCommand: "/mnt/c/Users/user/WebstormProjects/project/node_modules/hermes-engine/%OS-BIN%/hermes",This solved the initial issue of not being able to build becasue hermes executable was not found, however with this fix in place build is still failing with:
...because it is looking for
node_modulesfolder in wrong location; the correct location is the same as in hermesCommand,/mnt/c/Users/user/WebstormProjects/project/node_modules.Building works with
enableHermes: false, so it only fails with hermes is enabled.Any suggestion how to get around this?
My full react config from gradle:
EDIT:
I figured out that one can also use relative path for
hermesCommand, which is a bit different thancliPath. Seems like one has to pointhermesCommand2 levels higher in directory structure (when compared to cliPath):EDIT2 / SOLUTION:
By digging through the source code I found that
composeSourceMapsPathconfig key exists, so my whole react config looks like this:This got me pass the issue with
compose-source-maps.jsand I think files were successfully processed by hermes. However, there seems to still be an issue withcode-push, since build fails with...so this time code-push is looking node_modules in wrong location. I think this issue is out of scope here, so I guess I should check Microsoft's github regarding this.