![在 npm 中,为什么全局包默认设置了一个具有 root 权限的目录?](https://linux22.com/image/1592424/%E5%9C%A8%20npm%20%E4%B8%AD%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E5%85%A8%E5%B1%80%E5%8C%85%E9%BB%98%E8%AE%A4%E8%AE%BE%E7%BD%AE%E4%BA%86%E4%B8%80%E4%B8%AA%E5%85%B7%E6%9C%89%20root%20%E6%9D%83%E9%99%90%E7%9A%84%E7%9B%AE%E5%BD%95%EF%BC%9F.png)
npm i -g @angular/cli
我目前正在学习 Angular 和 npm。今天我尝试在 Fedora 上进行操作,但安装完成后,我在终端中看到(为方便起见,我缩短了消息):
npm WARN checkPermissions Missing write access to /usr/lib/node_modules
于是我使用 Google 查了一下这是什么意思。我发现这个 npm 解释这篇文章让我另一篇 npm 文章更详细地描述了这个错误。后一篇文章指出:
如果在尝试全局安装包时看到 EACCES 错误,您可以执行以下操作之一:
使用节点版本管理器重新安装 npm(推荐),
或者
手动更改 npm 的默认目录
作为一种快速修复,上述两种解决方案看起来都不错。
但是由于我对 Linux 有一些经验,我开始疑惑:为什么我必须安装另一个软件,或者为什么我甚至必须更改一些配置?换句话说,为什么 npm 的默认配置和 Fedora 的默认配置需要我调整其中一个才能不出现任何错误?
在问了自己这些问题之后,我认为问题可能出在我的 npm 配置上。很可能我自安装以来没有更改任何内容,但谁知道呢?所以,我决定重新安装 npm。为确保万无一失,我在卸载后重新启动了计算机。重新安装后,我npm i -g @angular/cli
再次尝试 - 但出现了同样的错误。
然后我想:也许这不是 npm 的问题,也许是我的 Fedora 安装的问题?我当然不想因为这样的原因重新安装 Fedora。所以,我在 Google 上检查了 Fedora 对目录的默认权限是否与默认/usr/lib/node_modules
权限相同。对于我的目录,对于和(甚至对于),所有者和组都是,并且只有所有者具有写入权限。我找到的唯一来源是“Fedora 26 安装指南”(虽然我安装了 Fedora 29),该文档建议我查看/usr
/usr/lib
/usr/lib/node_modules
/usr/lib/node_modules/npm
root root
文件系统层次结构标准 2.3对于目录结构。由于我期望node_modules
分配 npm 所需的权限,因此我只检查了/usr
和/usr/lib
。对于/usr
目录,FHS 似乎没有说明任何有关权限的信息;对于/usr/lib
目录,它说明:
/usr/lib 包含目标文件、库和内部二进制文件,它们不打算由用户或 shell 脚本直接执行。[22]
这些信息也没什么帮助。
最终,我得出结论,我仍然不明白导致我得到的错误的真正原因是什么。所以现在我想问:
- npm 是否必须以默认配置的方式放置新包
/usr/lib/node_modules
? - 如果是,那么 Fedora 是否为这些目录设置了应该/应当/可能具有的一些其他默认权限?
- 如果没有,是不是因为我可能意外更改了 Fedora 安装中这些目录的权限?
- 如果不是,是不是因为我没有用 root 权限安装 npm 包?这似乎也是一个解决办法,但是 npm 文档里没有提到这样的解决办法。
- 如果不是,是不是因为我试图全局安装 npm 包,而实际上我不应该这样做?如果是这样,为什么会有这种可能性?
- 有什么我不明白或遗漏的地方吗?也许我缺少一些(最新的)文档?
更新:我忘了指出我以普通用户身份而不是 root 身份运行所有命令。
答案1
您没有说明以哪个用户身份运行该程序,但我假设不是 root?在这种情况下,错误是正确的,但也是意料之中的,因为普通用户不应该能够安装到系统目录中。
无论如何,您都不应该使用npm
Fedora 打包的 Node.js 来全局安装软件包,因为它会让您陷入 rpm 管理和 npm 管理模块的混乱之中/usr/lib/node_modules
。
不幸的是,与其他语言环境不同,Node.js 不支持拥有两个单独的全局模块目录(一个用于/usr
由系统打包管理的模块,另一个用于/usr/local
由语言环境自己的工具管理的模块),因此,如果不对 npm 进行大量修补(我们并不想这样做),我们就无法以合理的方式实现这一点。即使可以进行这样的拆分,您仍然需要 root 身份才能进行全局安装,就像您对 perl、python 或 ruby 所做的那样。
据我所知,Node.js 不鼓励全局安装 - 上游的观点是你应该在每个项目中本地安装项目所需的模块。