react-native
react-native copied to clipboard
NODE_BINARY in .xcode.env not working
Description
I would like to use the .xcode.env to set my node version. My .xcode.env looks like:
export NODE_BINARY=$(command -v node)
When I execute this command in a terminal window, it returns the proper node version. I've tested, and the only way I can set the node version is using Build Phases -> Bunde React Native Code and Images -> and exporting NODE_BINARY in the shell commands there to the absolute path:
export NODE_BINARY=/Users/myuser/.nvm/versions/node/v14.18.1/bin/node
Can anyone suggest why NODE_BINARY is not being set through the .xcode.env file? Do I have to take any extra steps to use this during archive?
Version
0.70.4
Output of npx react-native info
System: OS: macOS 12.6 CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz Memory: 23.84 MB / 32.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 14.18.1 - ~/.nvm/versions/node/v14.18.1/bin/node Yarn: 1.22.18 - ~/.nvm/versions/node/v14.18.1/bin/yarn npm: 6.14.15 - ~/.nvm/versions/node/v14.18.1/bin/npm Watchman: 2022.03.21.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.3 - /Users/micahsklut/.rbenv/shims/pod SDKs: iOS SDK: Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1 Android SDK: API Levels: 29, 30, 31 Build Tools: 29.0.2, 30.0.2, 30.0.3, 31.0.0 System Images: android-29 | Intel x86 Atom_64, android-29 | Google APIs Intel x86 Atom_64, android-30 | Google APIs Intel x86 Atom Android NDK: Not Found IDEs: Android Studio: 2021.3 AI-213.7172.25.2113.9123335 Xcode: 14.2/14C18 - /usr/bin/xcodebuild Languages: Java: 1.8.0_292 - /usr/bin/javac npmPackages: @react-native-community/cli: Not Found react: 18.1.0 => 18.1.0 react-native: ^0.70.4 => 0.70.6 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found
Steps to reproduce
Run Archive. The system node is being used, unless I set it as explained above.
Snack, code example, screenshot, or link to a repository

in my case it was NVM. Either let nvm go or reconfigure it In your build phases scripts
if [[ -s "$HOME/.nvm/nvm.sh" ]]; then
. "$HOME/.nvm/nvm.sh"
elif [[ -x "$(command -v brew)" && -s "$(brew --prefix nvm)/nvm.sh" ]]; then
. "$(brew --prefix nvm)/nvm.sh"
fi
In my case I had to add export NODE_BINARY=$(command -v node)\n
to the PODS build phases script tail, .xcode.env
seemed to make no difference
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\nexport NODE_BINARY=$(command -v node)\n";
Running react-native": "0.69.7"
on arm64
Apparently this is caused by nvm
A less invasive workaround (that breaks nvm):
ln -s $(which node) /usr/local/bin/node
nvm is common enough that I would suggest this should work out of the box.
Loading nvm from within .xcode.env
seems to resolve this for me:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
export NODE_BINARY=$(command -v node)
In my Xcode build logs show me this error:
../node_modules/react-native/scripts/xcode/with-environment.sh: line 35: node: command not found
But after errors, show "Now using node v20.7.0." and this happen too with Upload Debug Symbols to Sentry build phase. I'm using Xcode 14.3.1 and RN v0.69.12. Everything works on terminal (iTerm + zsh)
The problem is that Xcode scripts works in a different environment than a regular terminal/ Xcode also overrides some basic ENV var that can shadow and mask other variables we might set.
If you don't have node in the default PATHs, like /usr/local/bin
, for example, Xcode is not able to find it.
A simple solution could be to create a symlink to node in /usr/local/bin
:
sudo ln -s $(command -v node) /usr/local/bin/node
We are investigating better way to handle this, but we haven't found a robust approach yet, unfortunately. :(
The problem is that Xcode scripts works in a different environment than a regular terminal/ Xcode also overrides some basic ENV var that can shadow and mask other variables we might set.
If you don't have node in the default PATHs, like
/usr/local/bin
, for example, Xcode is not able to find it. A simple solution could be to create a symlink to node in/usr/local/bin
:sudo ln -s $(command -v node) /usr/local/bin/node
We are investigating better way to handle this, but we haven't found a robust approach yet, unfortunately. :(
In my case, Xcode can find node (using the ,export NVM_DIR=path/to/.nvm
approach) but can't find command
, that is a built-in shell library.
Sounds weird.
@lucianomlima yeah, that's definitely very weird.
Can you try add a script phase after building just calling which command
? :/
which command
shows me : command: shell built-in command
but I do some tests and I realize that nothing going work with Xcode build and .xcode.env
.
Now my .xcode.env
is:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" --no-use
nvm use default # I need to put this because when use nvm current returns none
export NODE_BINARY=$NVM_DIR/versions/node/v20.7.0/bin/node
echo $NVM_DIR # Prints /Users/luciano.lima/.nvm
echo $NODE_BINARY # Prints /Users/luciano.lima/.nvm/versions/node/v20.7.0/bin/node
And, on Xcode log, I have these messages:
Now using node v20.7.0 (npm v10.1.0)
/Users/luciano.lima/.nvm # echo $NVM_DIR
/Users/luciano.lima/.nvm/versions/node/v20.7.0/bin/node # echo $NODE_BINARY
Node found at: /Users/luciano.lima/.nvm/versions/node/v20.7.0/bin/node
And some time later:
+ type node
+ echo 'error: node not found! Modules won'\''t be collected.' 'Please export NODE_BINARY in '\''Build Phase'\'' - '\''Bundle React Native code and images'\''' 'to an absolute path of your node binary. Check your node path by '\''which node'\''.'
error: node not found! Modules won't be collected. Please export NODE_BINARY in 'Build Phase' - 'Bundle React Native code and images' to an absolute path of your node binary. Check your node path by 'which node'.
+ exit 0
Command PhaseScriptExecution emitted errors but did not return a nonzero exit code to indicate failure
So, even using an absolute path to NODE_BINARY, build script phase fails.
The only way that make things works is with symlink like @cipolleschi suggests. Now my .xcode.env
have only this:
export NODE_BINARY=/usr/local/bin/node
And now finally works. 🤷
From which script phase the message:
+ type node
+ echo 'error: node not found! Modules won'\''t be collected.' 'Please export NODE_BINARY in '\''Build Phase'\'' - '\''Bundle React Native code and images'\''' 'to an absolute path of your node binary. Check your node path by '\''which node'\''.'
error: node not found! Modules won't be collected. Please export NODE_BINARY in 'Build Phase' - 'Bundle React Native code and images' to an absolute path of your node binary. Check your node path by 'which node'.
+ exit 0
Command PhaseScriptExecution emitted errors but did not return a nonzero exit code to indicate failure
arrives? I have no memory of any of our scripts emitting that message! Could it be a third party library?
The problem is likely that that script is not using loading the with-environment.sh
script that is responsible to load the .xcode.env
. Without loading that, it is expected not to find the ENV vars.
It's from @sentry/react-native and my script build phase is
export SENTRY_PROPERTIES=sentry.properties
export EXTRA_PACKAGER_ARGS="--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map"
set -e
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
SENTRY_CLI="../node_modules/@sentry/cli/bin/sentry-cli"
/bin/sh -c "$WITH_ENVIRONMENT \"$SENTRY_CLI react-native xcode $REACT_NATIVE_XCODE\""
/bin/sh ../node_modules/@sentry/react-native/scripts/collect-modules.sh
Maybe the last line is where the problem is? I'll try to add WITH_ENVIRONMENT
to it.
i think i'm getting a similar issue
Node found at: /opt/homebrew/bin/node
/Users/adamwright/Documents/Development/AB3MobileUpgrade/AB3MobileUpgrade/ios/Pods/../../node_modules/react-native/React/FBReactNativeSpec/../../scripts/react_native_pods_utils/script_phases.sh: line 34: /opt/homebrew/bin/node: No such file or directory
Command PhaseScriptExecution failed with a nonzero exit code
My .xcode.env is
# This `.xcode.env` file is versioned and is used to source the environment
# used when running script phases inside Xcode.
# To customize your local environment, you can create an `.xcode.env.local`
# file that is not versioned.
# NODE_BINARY variable contains the PATH to the node executable.
#
# Customize the NODE_BINARY variable here.
# For example, to use nvm with brew, add the following line
# . "$(brew --prefix nvm)/nvm.sh" --no-use
export NODE_BINARY=$(command -v node)export NODE_BINARY=/opt/homebrew/bin/node
but my node path when running which node
is - /usr/local/bin/node
How can i fix this?
Hey @adamjw3! Your Xcode env has 2 export NODE_BINARY
on the same line.
That would not work.
You should have either
export NODE_BINARY=$(command -v node)
Or
export NODE_BINARY=/usr/local/bin/node
@cipolleschi thanks, they are on two lines in the file and it was auto generated like that! i commented out
export NODE_BINARY=$(command -v node)
and updated the other with my node path
export NODE_BINARY=/usr/local/bin/node
project now builds
Thanks
I am using RN version 0.72.3, which can run, package and flash back. I feel that it is the reason for switching to the default version with NVM. I have added a script here, and switching to 20 or above is normal. It should be 18, but our team is using 20, so switching to 20 is necessary
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
nvm use 20
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh
What worked for us was to get the NVM directory:
export NODE_BINARY=$HOME/.nvm/nodes/versions/v18.0.0/bin/node
We have NVM setup in our README so could reasonably expect local devs to have that set, and doesn't to explicitly state the node version. Then, it runs same locally and on CircleCi.
The problem is that Xcode scripts works in a different environment than a regular terminal/ Xcode also overrides some basic ENV var that can shadow and mask other variables we might set.
If you don't have node in the default PATHs, like
/usr/local/bin
, for example, Xcode is not able to find it. A simple solution could be to create a symlink to node in/usr/local/bin
:sudo ln -s $(command -v node) /usr/local/bin/node
We are investigating better way to handle this, but we haven't found a robust approach yet, unfortunately. :(
This analysis is correct. I solved this problem by completely uninstalling node and then downloading the .pkg installation from the node.js ,because the installation location of the installation package is /usr/local/bin/node by default.
Just adding more info in case it's helpful. I'm using Homebrew and this is happening too, right after downgrading from node 20 to node 18. Not using Expo, RN 0.70.6. Here are some of the xcode logs when the error occurs:
...Desktop/Inventory/ios/Pods/../../node_modules/react-native/React/FBReactNativeSpec/../../scripts/xcode/with-environment.sh: line 35: .xcode.env: command not found .../Desktop/Inventory/ios/Pods/../../node_modules/react-native/React/FBReactNativeSpec/../../scripts/xcode/with-environment.sh: line 35: node: command not found [Warning] You need to configure your node path in the environment. You can set it up quickly by running: echo 'export NODE_BINARY=' > .xcode.env in the ios folder. This is needed by React Native to work correctly. We fallback to the DEPRECATED behavior of finding . This will be REMOVED in a future version. You can read more about this here: https://reactnative.dev/docs/environment-setup#optional-configuring-your-environment [Error] Could not find node. It looks like that the .xcode.env or .xcode.env.local Command PhaseScriptExecution failed with a nonzero exit code
I have .xcode.env inside my ios folder with the line: export NODE_BINARY=$(command -v node). command -v node prints out the correct path(/opt/homebrew/opt/node@18/bin/node). Switching out $(command -v node) with that path works.
I get now that Xcode runs in a different environment that doesn't have access to variables that the terminal has, but it was working before I changed the node version, and that is all I changed, so it seems weird that it suddenly wouldn't work.
Note, this other issue seems to suggest the .xcode.env thing will fix it, so just referencing here that that solution does not work: https://github.com/facebook/react-native/issues/33695
This fixed the issue for me https://stackoverflow.com/a/66497247/6590549. I had a symlinked version of node that was node longer actually installed via nvm.
Apparently this is caused by
nvm
A less invasive workaround (that breaks nvm):
ln -s $(which node) /usr/local/bin/node
The problem is that Xcode scripts works in a different environment than a regular terminal/ Xcode also overrides some basic ENV var that can shadow and mask other variables we might set. If you don't have node in the default PATHs, like
/usr/local/bin
, for example, Xcode is not able to find it. A simple solution could be to create a symlink to node in/usr/local/bin
:sudo ln -s $(command -v node) /usr/local/bin/node
We are investigating better way to handle this, but we haven't found a robust approach yet, unfortunately. :(
This analysis is correct. I solved this problem by completely uninstalling node and then downloading the .pkg installation from the node.js ,because the installation location of the installation package is /usr/local/bin/node by default.
Thanks for good answer. The important thing is uninstalling unused node version.