问题

在 WSL 里使用 npm install 安装包的时候出现如下的权限错误:

root@pi ~# npm install -g npm
npm ERR! code EACCES
npm ERR! syscall rename
npm ERR! path /usr/lib/node_modules/.staging/npm-18aca6f9/node_modules/yargs
npm ERR! dest /usr/lib/node_modules/.staging/yargs-765698bc
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, rename '/usr/lib/node_modules/.staging/npm-18aca6f9/node_modules/yargs' -> '/usr/lib/node_modules/.staging/yargs-765698bc'
npm ERR!  [OperationalError: EACCES: permission denied, rename '/usr/lib/node_modules/.staging/npm-18aca6f9/node_modules/yargs' -> '/usr/lib/node_modules/.staging/yargs-765698bc'] {
npm ERR!   cause: [Error: EACCES: permission denied, rename '/usr/lib/node_modules/.staging/npm-18aca6f9/node_modules/yargs' -> '/usr/lib/node_modules/.staging/yargs-765698bc'] {
npm ERR!     errno: -13,
npm ERR!     code: 'EACCES',
npm ERR!     syscall: 'rename',
npm ERR!     path: '/usr/lib/node_modules/.staging/npm-18aca6f9/node_modules/yargs',
npm ERR!     dest: '/usr/lib/node_modules/.staging/yargs-765698bc'
npm ERR!   },
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'rename',
npm ERR!   path: '/usr/lib/node_modules/.staging/npm-18aca6f9/node_modules/yargs',
npm ERR!   dest: '/usr/lib/node_modules/.staging/yargs-765698bc'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2020-05-18T14_52_40_128Z-debug.log

我已经是 root 用户了,文件夹的权限也没什么问题,所以这个错误很是费解,查询了一大圈后,最终解决了问题,这里记录一下可能出现的解决方法。

解决方法

1. 使用 npm config set unsafe-perm=true

这个是 npm 本身的权限设计,如果你只是在 wsl 里面遇到权限问题,大概这个方法并不适用,不过可以先试一下。

2. VSCode 的 Remote WSL

网上说关了 wsl 就可以了,我这里并没有安装 VSCode 的 Remote WSL , 所以并不适用。

3. 修改 prefix 更换目录

npm config set prefix="${HOME}/npm-global"

我尝试修改成上面之后还是报权限错误,一度以为这个方法不行,又经过一番搜索后,觉得非常可能是 Symlink problems ,然后又将上面的 prefix 换到了挂在的 E 盘下,居然神奇的可以了。

npm config set prefix="/mnt/e/npm-global"

这个问题最早2016年提出,到现在2020年还没有完全解决,真是 ridiculous.

参考

https://github.com/Microsoft/WSL/issues/2097
https://github.com/Microsoft/WSL/issues/14
https://github.com/MicrosoftDocs/WSL/issues/26