Android Studio 构建时报 Cannot run program "node"

Cannot run program "node" in directory ".../uapp_reactnative_ai_assistant_order/android": error=2, No such file or directory

阅读 -- 次 参与评论

现象

在 Android Studio 中 Sync / Run Android 工程时,Gradle 配置阶段失败:

Cannot run program "node"
in directory ".../uapp_reactnative_ai_assistant_order/android":
error=2, No such file or directory

报错位置:

node_modules/@react-native-community/cli-platform-android/native_modules.gradle

Android 工程在 settings.gradle 中加载了 React Native 脚本:

apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle")

这个脚本会在 Gradle 配置阶段执行 node,用于读取 React Native CLI 配置。

原因

本机命令行里 node 是正常的,但 Android Studio 是从 macOS GUI 环境启动的,不一定继承 zsh / nvm 初始化后的 PATH

命令行可以找到:

/Users/xxxx/.nvm/versions/node/v24.11.0/bin/node

但 Android Studio 拉起的 Gradle Daemon 中,PATH 只有:

/usr/bin:/bin:/usr/sbin:/sbin

这里没有 nvm 或 Homebrew 的 node 路径,所以 RN 脚本执行 "node" 时找不到可执行文件。

先解释报错

报错核心是:

Cannot run program "node": No such file or directory

意思不是 node 一定没安装,而是:当前运行 Gradle 的进程找不到名叫 node 的程序

React Native 的 Android 构建脚本里会直接执行:

node ...

但它没有写完整路径,例如:

/opt/homebrew/bin/node

所以系统需要自己去“搜索”哪里有 node

PATH 是什么

PATH 是一个环境变量,可以理解成“命令搜索目录列表”。

当程序执行:

node

系统会按 PATH 里的目录从左到右找:

/opt/homebrew/bin
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

如果某个目录下面有 node,就执行它。

比如你的机器上有:

/opt/homebrew/bin/node

那只要 PATH 里包含 /opt/homebrew/bin,执行 node 就能找到。

为什么终端里能找到,Android Studio 找不到 你在终端里能执行 node,是因为终端启动时会加载 zsh 配置,比如 .zshrc、nvm 配置等。

但 Android Studio 通常是从 Dock、Launchpad、Finder 启动的,它不是从你的 zsh 终端启动的,所以它不一定会加载 .zshrc

结果就是:

终端里的 PATH:有 node 路径
Android Studio/Gradle PATH:可能只有 /usr/bin:/bin:/usr/sbin:/sbin

之前看到 Gradle Daemon 的 PATH 类似:

/usr/bin:/bin:/usr/sbin:/sbin

这里面没有 /opt/homebrew/bin,所以找不到 Homebrew 安装的 node

解决办法

把 node 所在目录写入 macOS GUI 环境 PATH,并停掉旧的 Gradle Daemon:

launchctl setenv PATH "/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

cd /Users/json.luo/AndroidProject/uapp_reactnative_ai_assistant_order/android
./gradlew --stop

然后完全退出 Android Studio,再重新打开项目,重新 Sync / Run。

launchctl 是什么

launchctl 是 macOS 用来管理系统启动服务和图形界面 App 环境的工具。

简单理解:

终端环境变量 -> 给终端和它启动的子进程用
launchctl setenv -> macOS 图形界面后续启动的 App

所以这条命令不是给当前 shell 临时用,而是告诉 macOS:

以后从图形界面启动的 App,也带上这个 PATH

setenv 是什么

setenv 就是 “set environment variable”,设置环境变量。

这段:

launchctl setenv PATH "..."

意思是:

 macOS 图形环境里的 PATH 设置成后面这一串目录

为什么要写这些目录

这一串:

/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

用冒号 : 分隔,每一段都是一个目录。

含义大概是:

/opt/homebrew/bin   Apple Silicon Mac Homebrew 常用命令目录,node 通常在这里
/usr/local/bin      Intel Mac 或部分手动安装命令目录
/usr/bin            系统自带命令目录
/bin                系统基础命令目录
/usr/sbin           系统管理命令目录
/sbin               系统基础管理命令目录

/opt/homebrew/bin 放最前面,是为了优先找到 Homebrew 安装的 node

为什么执行后要重启 Android Studio

环境变量只会在“进程启动时”继承。

如果 Android Studio 已经打开了,它已经拿到了旧的 PATH。你后来执行:

launchctl setenv PATH ...

不会自动改变已经运行中的 Android Studio。

所以需要:

退出 Android Studio
重新打开 Android Studio
重新 Sync/Run

新的 Android Studio 进程才会继承新的 PATH。

Gradle Daemon 也是一样,所以我们之前还执行了:

./gradlew --stop

意思是停掉旧 Gradle 后台进程,避免它继续拿旧 PATH。

** 这个修复有没有改代码**

没有。

它没有改项目代码,也没有改 React Native 脚本,也没有安装 node。

它只是告诉 macOS:

以后启动 GUI App 时,把 Homebrew 的命令目录也放进 PATH

这样 Gradle 执行 node 时就能找到。

验证

用同样的 PATH 在命令行验证 Gradle 可以通过:

PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" ./gradlew :module_main:compileDebugKotlin

输出结果:

BUILD SUCCESSFUL

结论

这不是工程代码问题,也不是 React Native 脚本损坏,而是 Android Studio 启动环境缺少 node 路径。

修复 macOS GUI 环境的 PATH,停止旧 Gradle Daemon,并重启 Android Studio 后,问题解决。

评论

使用 GitHub 登录参与讨论。