如何修复 npm 中的 EACCES:Permission Denied 错误
你运行 npm install -g 来安装一个 CLI 工具,结果没有得到干净的安装,而是看到了这样的报错:
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall access
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
这个 npm EACCES 错误是开发者在 macOS 和 Linux 上最常遇到的 Node.js 权限错误之一。下面来分析它发生的原因以及如何正确地修复它。
核心要点
- EACCES 错误发生的原因是 npm 尝试写入像
/usr/local/lib/node_modules这样的 root 所有目录,而你的用户账户无权访问该目录。 - 推荐的修复方式是通过类似 nvm 的版本管理器来安装 Node.js,它会将所有文件放置在你的主目录内。
- 或者,你可以通过修改 npm 的 prefix 并更新 PATH,让 npm 使用由用户所有的全局目录。
- 避免使用
sudo npm install -g—— 这会导致长期的权限问题并带来安全风险。 - 对于一次性的 CLI 使用场景,
npx可以在完全不需要全局安装的情况下运行包。
为什么会出现 npm Permission Denied 错误
当你运行 npm install -g 时,npm 会写入像 /usr/local/lib/node_modules 这样的系统级目录。如果你使用官方安装器或系统包管理器安装了 Node.js,那么该目录通常归 root 所有。你的普通用户账户没有写入权限,因此安装会失败。
这是 Unix 系统的一项安全特性,而不是一个 bug。修复方法不是绕过这些保护机制 —— 而是给 npm 一个你的用户已经拥有的位置。
重要区分: 本文讨论的是 全局安装 的权限错误。如果你在本地项目的
node_modules文件夹中遇到权限错误,原因是不同的 —— 通常是项目目录中的文件归属不匹配。
修复 npm 全局安装权限:两种安全方案
方案一:使用版本管理器重新安装 Node.js(推荐)
npm 官方推荐使用 Node 版本管理器(如 nvm)来彻底避免 EACCES 错误。当 nvm 安装 Node 时,它会将所有内容放在你的主目录内 —— 该位置默认归你的用户所有。完全不需要 root 权限。
安装 nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/install.sh | bash
然后安装 Node:
nvm install --lts
之后,npm install -g 就能在无需 sudo 或修改权限的情况下正常工作。作为额外的好处,nvm 还能让你为每个项目切换不同的 Node 版本 —— 这是其他方案做不到的。
注意: 如果你已经配置了自定义的 npm prefix,nvm 会在内部管理自己的 prefix。不要在同一环境中混用这两种方式,因为它们会发生冲突。
方案二:配置一个用户所有的 npm 全局目录
如果你不想使用 nvm,可以将 npm 的全局安装位置重定向到一个你的用户拥有的目录。这是 npm 官方文档 中描述的替代方案。
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
然后将 bin 目录添加到 PATH。对于 bash,将以下内容添加到 ~/.profile 或 ~/.bashrc:
export PATH=~/.npm-global/bin:$PATH
对于 zsh,将同样的内容添加到 ~/.zshrc,然后重新加载:
source ~/.zshrc
通过在不使用 sudo 的情况下安装一个包来验证它是否生效:
npm install -g npm-check-updates
Discover how at OpenReplay.com.
那 sudo npm install -g 呢?
请避免使用它。在 npm 中使用 sudo 会让安装的文件归 root 所有,这会引发后续的权限问题,并带来真正的安全风险 —— 一个恶意或被攻陷的包会以提升的权限运行。这是一个会让事情变得更糟的短期权宜之计。
一个快速的替代方案:使用 npx
如果你只是偶尔需要一个 CLI 工具,你可能根本不需要全局安装。npx 可以运行包而无需全局安装,它会使用本地包或临时获取一个:
npm create vite@latest
无需权限,也不涉及任何全局目录。
你应该选择哪种修复方式?
| 场景 | 最佳方案 |
|---|---|
| 管理多个项目的开发者 | nvm |
| 单一机器,无需版本切换 | 自定义 npm prefix |
| 一次性的 CLI 工具使用 | npx |
结论
npm install -g EACCES 错误的根本原因几乎总是相同的:npm 试图写入一个 root 所有的目录。从源头修复这种不匹配 —— 无论是通过使用 nvm,还是让 npm 指向一个你拥有的目录 —— 错误就会永久消失。
常见问题
你可以,但不应该这么做。使用 sudo 安装的包会归 root 所有,这会在 npm 稍后以你的普通用户身份更新或删除它们时引发更多的权限问题。它还会让你的系统暴露于安全风险之中,因为任何安装脚本都会以提升的权限运行。请改用 nvm 或自定义 prefix。
全局安装会写入像 /usr/local/lib/node_modules 这样的系统目录,在大多数系统上这些目录归 root 所有。本地安装则写入项目目录内的 node_modules 文件夹,而该目录本来就归你所有。这就是为什么 npm install 在本地能正常运行,但在没有正确配置的情况下全局安装会失败。
是的,之前在旧 prefix 下安装的包将在新 prefix 下不可用。你需要在新位置重新安装它们。在更改 prefix 之前,使用 npm list -g --depth=0 列出你的旧全局包,然后在新目录设置好且 PATH 更新后重新安装它们。
通常不会。Windows 使用不同的权限模型,npm 在 Windows 上默认的全局安装路径已经位于用户的 AppData 文件夹内。EACCES 错误几乎专属于 macOS 和 Linux,因为这些系统采用 Unix 风格的文件归属来控制对像 /usr/local 这样的系统目录的写入访问。
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.