我准备在家里开始一些node.js开发,但在全局安装npm软件包时偶然发现了一些奇怪的行为。
我使用WebStorm作为我的IDE,并希望使用ECMAScript6功能,这意味着我必须通过使用Babel来转换WebStorm所做的来源。
所以我尝试在全球范围内安装Babel:
$ sudo npm install -g babel-cli
所发生的情况是,root用户可以很好地访问这些文件,babel-cli
目录及其中的所有文件和目录看起来都很好,只要看起来像root
。当我尝试查看包或使用它作为另一个用户时出现问题:
$ ls -l /usr/lib/node_modules/babel-cli/
ls: cannot access '/usr/lib/node_modules/babel-cli/lib': Permission denied
ls: cannot access '/usr/lib/node_modules/babel-cli/index.js': Permission denied
ls: cannot access '/usr/lib/node_modules/babel-cli/scripts': Permission denied
ls: cannot access '/usr/lib/node_modules/babel-cli/node_modules': Permission denied
ls: cannot access '/usr/lib/node_modules/babel-cli/package.json': Permission denied
ls: cannot access '/usr/lib/node_modules/babel-cli/README.md': Permission denied
ls: cannot access '/usr/lib/node_modules/babel-cli/bin': Permission denied
total 0
d????????? ? ? ? ? ? bin/
d????????? ? ? ? ? ? lib/
d????????? ? ? ? ? ? node_modules/
d????????? ? ? ? ? ? scripts/
-????????? ? ? ? ? ? index.js
-????????? ? ? ? ? ? package.json
-????????? ? ? ? ? ? README.md
我安装的软件包并不重要,它们都变成这样。
我在Ubuntu 16.04上使用node.js v6.3.0和npm 3.10.3。
我按照指示here新安装了node.js。如果我尝试更新npm
,那么全局npm目录也会发生同样的情况,除了root
之外,npm变得不可用。
当我将全局node_modules
列为用户时,我看到了
$ ll /usr/lib/node_modules/
total 8,0K
drwxr--r-- 6 nobody root 4,0K jul 15 23:50 babel-cli/
drwxr-xr-x 10 root root 4,0K jul 15 23:21 npm/
除nobody
拥有的目录外,我没有看到任何特别的内容。
安装软件包时当然没有错误。
npm和/或节点有问题吗? Ubuntu有问题吗?或者我如何安装节点?可能是什么原因 那会发生什么?
本地安装工作正常,对于babel-cli
包,将其安装为本地开发包是一种可接受的解决方法。我仍然想知道在全局安装软件包时会发生什么,以及为什么。
问题answered here。问题与npm
和node
无关。
答案 0 :(得分:7)
如果要全局安装软件包,只需使用不带sudo
的命令,如:
$ npm install -g <package>
如果您收到EACCES或权限错误,应该避免使用sudo
,但您应该修改您的权限,以便npm可以在没有sudo
的情况下运行。
如果您没有权限写入npm用于存储全局包的文件夹,则会引发这些错误。要解决这个问题,您可以先找到npm默认目录的路径:
$ npm config get prefix
在大多数系统上,它都是/usr/local
,您可以修复此文件夹的权限。如果该文件夹是/usr
或/usr/lib
,则您不应更改此目录的权限,因为它会导致某些问题,并且在这种情况下您不希望更改该目录的权限默认目录,您可以配置npm使用不同的目录。
如果您可以并且想要更改默认文件夹的权限,则可以使用:
$ sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
它会将npm目录的所有者更改为当前用户的名称。
如果您想更改npm的默认目录,可以先创建这个新文件夹:
$ mkdir ~/.npm-packages
然后,您配置npm以使用此新文件夹:
$ npm config set prefix '~/.npm-packages'
您还需要将此新文件夹添加到PATH
(例如使用〜/ .profile):
export PATH=~/.npm-packages/bin:$PATH
此时,您可以使用source ~/.profile
更新系统变量并测试以在不使用sudo
的情况下全局安装软件包。
您应该能够安装软件包而不会出现任何权限错误,因为npm将使用~/.npm-packages
文件夹。
您可以在npm documentation上找到有关此问题的更多信息。
答案 1 :(得分:0)
如果您更改用户而不是必须执行以下操作之一,因为当您安装npm时,您将以Root用户身份安装,但是在用户之后您更改了用户,这会给您权限错误,因为这表明您没有有权写入npm用于存储全局包和命令的目录。你可以通过以下方式解决这个问题: -
使用包管理器为您解决此问题。
如果您在Mac OS上全新安装节点,则可以使用Homebrew包管理器完全避免此问题。 Homebrew使用正确的权限开箱即用。
brew install node
OR
将npm的默认目录更改为另一个目录
有些时候您不想更改npm使用的默认目录(即/ usr)的所有权,因为这可能会导致一些问题,例如,如果您与其他用户共享系统。
相反,您可以配置npm以完全使用其他目录。在我们的例子中,这将是我们的主文件夹中的隐藏目录。
为全局安装创建一个目录:
mkdir ~/.npm-global
配置npm以使用新目录路径:
npm config set prefix '~/.npm-global'
打开或创建〜/ .profile文件并添加以下行:
export PATH=~/.npm-global/bin:$PATH
返回命令行,更新系统变量:
source ~/.profile
测试:在不使用sudo的情况下全局下载软件包。
npm install -g babel-cli
除了步骤2-4,您还可以使用相应的ENV变量(例如,如果您不想修改〜/ .profile):
NPM_CONFIG_PREFIX=~/.npm-global