react-native icon indicating copy to clipboard operation
react-native copied to clipboard

Fix path to node in .xcode.env.local

Open cipolleschi opened this issue 1 year ago • 6 comments

Summary: This change fixes https://github.com/facebook/react-native/issues/43285. Basically, when using a yarn alias to install pods, yarn creates a copy of the node and yarn executables and the command -v node command will return the path to that executable.

Differential Revision: D54542774

cipolleschi avatar Mar 05 '24 17:03 cipolleschi

This pull request was exported from Phabricator. Differential Revision: D54542774

facebook-github-bot avatar Mar 05 '24 17:03 facebook-github-bot

For the sake of fully talking this out:

I think there are drawbacks to hardcoding a path for node. This breaks the model of many version managers; for example, if i'm using nvm, this is going to store /Users/lizzi/.nvm/versions/node/v20.9.0/bin/node, which means if I decide to update my project's .nvmrc to 20.10.0, this will continue to have xcode use the older version of node.

I don't fully understand the original problem that this was trying to solve, so it's hard to suggest other fixes.

I see on https://github.com/facebook/react-native/pull/38879 you mention .xcode.env's command -v node is too late; is it late due to:

  1. when .xcode.env is loaded vs. when .xcode.env.local is loaded?
  2. when .xcode.env is generated?

If it's 1, can we evaluate command -v node each time in .xcode.env.local as we do in .xcode.env? If it's 2, can we generate .xcode.env earlier?

lindboe avatar Mar 05 '24 18:03 lindboe

Hi @lindboe in this change we are not hardcoding the path to node.

We are asking to the command type to return ALL the path to a node executable it knows and we are dropping the first one if it starts with /var, which is the path used by yarn to create the temporary folder.

So, this should work for all the other package managers as well.

The problem here is when the command -v node is used. When used in Xcode, Xcode loads a different ENV, with different variables. So, unless you have node in in your default /usr/bin path, for example, Xcode will not find node.

The only way to work around that is by using the absolute paths to the executable, which might be an absolute path provided by nvm.

As of priorities, .xcode.env.local has a higher priority than .xcode.env.

If it's 1, can we evaluate command -v node each time in .xcode.env.local as we do in .xcode.env?

No, this will leave you in the same state as not having the .xcode.env.local and if you don't have node in the default paths, the compilation will fail.

If it's 2, can we generate .xcode.env earlier?

We are already generating it at the earliest time: at pod install. The .xcode.env is dynamic and it uses the result of command -v node to populate the NODE_BINARY variable. The problem is that this file is sourced by Xcode and in Xcode, the command -v node returns an empty string if node in not in one of the paths I listed in https://github.com/facebook/react-native/pull/38879.

cipolleschi avatar Mar 06 '24 14:03 cipolleschi

Thanks @cipolleschi my understanding is improved. I'm still not clear about a couple of things, though, will break that into smaller parts:

Hardcoding path to node

in this change we are not hardcoding the path to node.

I am confused by this statement, when I pull down this patch and test it, the contents of my .xcode.env.local are export NODE_BINARY=/Users/lizzi/.nvm/versions/node/v20.10.0/bin/node. That is what I would consider a hard-coded path to node, and would cause XCode to continue to use 20.10.0 node even if I changed what version I'm using with nvm.

Auto-generating .xcode.env.local

I am still somewhat confused, if we can auto-generate the correct contents for .xcode.env.local, why we would not instead generate those contents inside xcode.env, and leave .xcode.env.local for local manual use if anyone needs to override those settings? Does that make sense?

Making version managers work in XCode scripts

Tools like nvm not working in XCode shell scripts is maybe an issue with their setup instructions, and I even see on the react native setup docs is mentions this: https://reactnative.dev/docs/environment-setup#optional-configuring-your-environment. If you move setup to .zshenv, and change the scripts to use /bin/zsh (which is the default shell on Macs now anyways), XCode should be able to find node.

Summary

I think it might be preferable to always dynamically evaluate the path to node on each script run, and instead help anyone with a version manager understand that they can either:

  1. Set up non-login, non-interactive shell configuration for their version manager, or
  2. Hardcode a path to node in .xcode.env.local if they'd prefer, but this is currently not the easiest if using expo prebuild

lindboe avatar Mar 07 '24 20:03 lindboe

Sorry for the long delay. I was on PTO for a few weeks. You gave me some cool ideas, @lindboe! Give me some days to test them out and I'll get back to this!

cipolleschi avatar Apr 03 '24 13:04 cipolleschi

@cipolleschi any updates here? Thanks in advance!

mattkrepp avatar May 10 '24 01:05 mattkrepp