TL;DR
确认node是否有修改源代码文件夹的权限;包括确认文件owner和文件修改权限。
过程 & 思路
日前在服务器上安装node-sass
的过程中遇到了以下错误:
[root@VM_0_7_centos JerryChan31.github.io]# npm i
> node-sass@4.14.1 install /root/JerryChan31.github.io/node_modules/node-sass
> node scripts/install.js
Unable to save binary /root/JerryChan31.github.io/node_modules/node-sass/vendor/linux-x64-72 : Error: EACCES: permission denied, mkdir '/root/JerryChan31.github.io/node_modules/node-sass/vendor'
at Object.mkdirSync (fs.js:840:3)
at sync (/root/JerryChan31.github.io/node_modules/mkdirp/index.js:72:13)
at Function.sync (/root/JerryChan31.github.io/node_modules/mkdirp/index.js:78:24)
at checkAndDownloadBinary (/root/JerryChan31.github.io/node_modules/node-sass/scripts/install.js:114:11)
at Object.<anonymous> (/root/JerryChan31.github.io/node_modules/node-sass/scripts/install.js:157:1)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) {
errno: -13,
syscall: 'mkdir',
code: 'EACCES',
path: '/root/JerryChan31.github.io/node_modules/node-sass/vendor'
}
> core-js@2.6.11 postinstall /root/JerryChan31.github.io/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!
The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
> https://opencollective.com/core-js
> https://www.patreon.com/zloirock
Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)
> ejs@2.7.4 postinstall /root/JerryChan31.github.io/node_modules/ejs
> node ./postinstall.js
Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)
> node-sass@4.14.1 postinstall /root/JerryChan31.github.io/node_modules/node-sass
> node scripts/build.js
Building: /usr/local/bin/node/bin/node /root/JerryChan31.github.io/node_modules/node-gyp/bin/node-gyp.js rebuild --verbose --libsass_ext= --libsass_cflags= --libsass_ldflags= --libsass_library=
gyp info it worked if it ends with ok
gyp verb cli [
gyp verb cli '/usr/local/bin/node/bin/node',
gyp verb cli '/root/JerryChan31.github.io/node_modules/node-gyp/bin/node-gyp.js',
gyp verb cli 'rebuild',
gyp verb cli '--verbose',
gyp verb cli '--libsass_ext=',
gyp verb cli '--libsass_cflags=',
gyp verb cli '--libsass_ldflags=',
gyp verb cli '--libsass_library='
gyp verb cli ]
gyp info using node-gyp@3.8.0
gyp info using node@12.16.1 | linux | x64
gyp verb command rebuild []
gyp verb command clean []
gyp verb clean removing "build" directory
gyp verb command configure []
gyp verb check python checking for Python executable "python2" in the PATH
gyp verb `which` succeeded python2 /usr/bin/python2
gyp verb check python version `/usr/bin/python2 -c "import sys; print "2.7.5
gyp verb check python version .%s.%s" % sys.version_info[:3];"` returned: %j
gyp verb get node dir no --target version specified, falling back to host node version: 12.16.1
gyp verb command install [ '12.16.1' ]
gyp verb install input version string "12.16.1"
gyp verb install installing version: 12.16.1
gyp verb install --ensure was passed, so won't reinstall if already installed
gyp verb install version not already installed, continuing with install 12.16.1
gyp verb ensuring nodedir is created /root/.node-gyp/12.16.1
gyp WARN EACCES user "root" does not have permission to access the dev dir "/root/.node-gyp/12.16.1"
gyp WARN EACCES attempting to reinstall using temporary dev dir "/root/JerryChan31.github.io/node_modules/node-sass/.node-gyp"
gyp verb tmpdir == cwd automatically will remove dev files after to save disk space
gyp verb command install [ '--node_gyp_internal_noretry', '12.16.1' ]
gyp verb install input version string "12.16.1"
gyp verb install installing version: 12.16.1
gyp verb install --ensure was passed, so won't reinstall if already installed
gyp verb install version not already installed, continuing with install 12.16.1
gyp verb ensuring nodedir is created /root/JerryChan31.github.io/node_modules/node-sass/.node-gyp/12.16.1
gyp WARN install got an error, rolling back install
gyp verb command remove [ '12.16.1' ]
gyp verb remove using node-gyp dir: /root/JerryChan31.github.io/node_modules/node-sass/.node-gyp
gyp verb remove removing target version: 12.16.1
gyp verb remove removing development files for version: 12.16.1
gyp WARN install got an error, rolling back install
gyp verb command remove [ '12.16.1' ]
gyp verb remove using node-gyp dir: /root/JerryChan31.github.io/node_modules/node-sass/.node-gyp
gyp verb remove removing target version: 12.16.1
gyp verb remove removing development files for version: 12.16.1
gyp ERR! configure error
gyp ERR! stack Error: EACCES: permission denied, mkdir '/root/JerryChan31.github.io/node_modules/node-sass/.node-gyp'
gyp ERR! System Linux 3.10.0-1062.9.1.el7.x86_64
gyp ERR! command "/usr/local/bin/node/bin/node" "/root/JerryChan31.github.io/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd /root/JerryChan31.github.io/node_modules/node-sass
gyp ERR! node -v v12.16.1
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
Build failed with error code: 1
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.2 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! node-sass@4.14.1 postinstall: `node scripts/build.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the node-sass@4.14.1 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2021-04-27T09_42_26_856Z-debug.log
网上一查,查到node-sass的Github issue,里面只提到了没有权限,但是没有提到如何修复权限问题。
中文网络下的搜索结果大部分也只是让人使用npm i --unsafe-perm node-sass
这样的命令来绕过问题。
下面是我解决这个问题的流程。
仔细看下这里的报错堆栈:
gyp ERR! configure error
gyp ERR! stack Error: EACCES: permission denied, mkdir '/root/JerryChan31.github.io/node_modules/node-sass/.node-gyp'
gyp ERR! System Linux 3.10.0-1062.9.1.el7.x86_64
gyp ERR! command "/usr/local/bin/node/bin/node" "/root/JerryChan31.github.io/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
这里提到的错误是,没有权限在/root/JerryChan31.github.io/node_modules/node-sass/.node-gyp
这个目录下创建这个文件夹。
首先要搞懂,是谁没有权限呢?下面的日志给出了答案:
gyp ERR! command "/usr/local/bin/node/bin/node" "/root/JerryChan31.github.io/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
这里说明了,执行创建文件夹操作的程序是/usr/local/bin/node/bin/node
,也就是node。
那为什么node会没有权限呢?linux 的权限系统可以简单分为两个层级:
- 文件所属用户与组;
- 用户对文件的权限;
我们cd
到/usr/local/bin
,执行ll | grep node
,可以看到:
drwxr-xr-x 6 1001 1001 4096 2月 18 2020 node
这里与文件权限相关的内容是前面的drwxr-xr-x
,代表读、写、执行权限情况;
后面的1001 1001
的含义分别是文件的拥有者
和所属的group
;
再回来看我要执行npm i
的目录:
[root@VM_0_7_centos ~]# ll | grep github
drwxrwxrwx 8 root root 4096 4月 27 17:42 JerryChan31.github.io
这说明我的这个文件夹,是归root
用户所有的。那么执行chown -R 1001:1001 JerryChan31.github.io/
,将文件拥有者修改为与node相同的1001,就意味着node有了该文件夹的权限。再重新执行npm install
,问题解决。