-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: fix @react-native-community/cli
not being found in monorepos
#47304
base: main
Are you sure you want to change the base?
Conversation
@cortinico has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
@@ -23,6 +23,14 @@ const deprecated = () => { | |||
); | |||
}; | |||
|
|||
function findCommunityCli(startDir = process.cwd()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is process.cwd()
in this context? It seems fragile to assume that's where the dependency is declared.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's where the react-native
command is being executed from, which should be project root. I am not familiar with use cases where it's being executed elsewhere.
@tido64 how do I reproduce this issue locally? I'm trying to understand what's going on with pnpm. |
Follow the repro steps in the description. |
@tido64 thanks for working with me on this one. I wonder if we can tweak this approach slightly. The way I could reproduce this locally was with Yarn Berry using the pnpm nodeLinker. As a more general solution, we can look at updating the function yarnPnpmWorkaround() {
const project = process.cwd();
if (module.paths.indexOf(project) === -1) {
module.paths.push(project)
}
} This way we get the default module lookup paths, but add the workaround for the issue you're seeing in monorepos with pnpm linking. We could do more to only apply this when needed? const isYarnBerryPnpm = () => /yarn\/[^1]/.test(process.env.npm_config_user_data) && execSync('yarn config get nodeLinker').toString().trim() === 'pnpm');
const isPnpm = () => /pnpm\//.test(process.env.npm_config_user_data)
const mustUpdatePaths = isPnpm() || isYarnBerryPnpm();
function updatePaths() {
if (!mustUpdatePaths) return;
yarnPnpmWorkaround();
} @robhogan thoughts? |
I think this is a big no-no. This changes the paths for everything. There are too many side-effects that can occur. Monorepos with a pnpm setup can reproduce this fairly consistently, but even with "normal" node_modules layout, there are no guarantees for how a package is hoisted. If there are multiple versions of CLI, but only one of RN, Yarn can (and probably will) hoist only RN to repo root, while leaving CLI in the individual packages. You'll run into the same issues there. |
IMO the original approach (assuming If we wanted to pick this into 0.76 it'd have to be non-breaking, and the safest way to do that is to fall back to a cwd-based resolution only if the assume-hoisted resolution fails (eg, (The blessed way to do this is theoretically with optional peer dependencies, but I don't know what the state of support is amongst package managers these days, and afaik |
Just so I don't misunderstand, you want this change in |
@react-native-community/cli
not being found in pnpm setups@react-native-community/cli
not being found in monorepos
I think it makes sense to go in My thinking is to put
Does that seem reasonable? |
My reason for going with cwd first is to avoid the scenario where we have multiple versions of React Native in a monorepo and the layout looks something like this:
We've hit similar scenarios before (albeit with Metro). |
Cool, that makes sense. Update to that please. Update: Discussed with @robhogan some more. If you update to the equivalent of this: try {
return require('@react-native-community/cli');
} catch {
return require(require.resolve('@react-native-community/cli', { paths: [startDir] }));
} and target |
a2bf26d
to
0c4b65d
Compare
Summary:
Fix
@react-native-community/cli
not being found in monorepos even though it is installed.Note that we are making the assumption that
process.cwd()
returns the project root. This is the same assumption that@react-native-community/cli
makes. Specifically,findProjectRoot()
has an optional argument that defaults toprocess.cwd()
:findProjectRoot()
loadConfig()
loadConfig()
gets called fromsetupAndRun()
, also without project root setAs far as I can see, the project root argument is only ever used in tests.
Changelog:
[GENERAL] [FIXED] - Fix
@react-native-community/cli
not being found in monoreposTest Plan:
react-native
to 0.76 microsoft/rnx-kit#3409yarn react-native config
Before:
After: The usual output of
react-native config