Node4环境下npm3执行npm install报ENOTDIR错误求助
问题根因
这个报错是npm 3.x的固有bug加上依赖未锁版本共同导致的:
- npm 3.10.x处理
@开头的scoped包(比如报错里的@types/node)时存在逻辑缺陷:如果.staging临时目录下有同名残留、或者依赖树里同一个scoped包存在多个版本引用,npm会误把目录路径当文件打开,直接抛出ENOTDIR错误。 - 你的项目没有锁定全量依赖版本(npm3默认不会自动生成锁文件),部分间接依赖近期发布了更新,自动拉取了高版本
@types/node,刚好触发了上述bug,这也是之前安装一直正常、最近突然报错的核心原因。 - 日志里的fsevents平台不兼容提示、node-fetch peer依赖提示都是非致命警告,和本次报错没有关系。
解决步骤(全程保留Node4 + npm3环境,不需要升级npm)
按顺序操作即可:
- 第一步:彻底清理坏的安装残留
进入项目根目录,执行以下命令:
# 删除已存在的node_modules目录 rm -rf node_modules # 清空npm本地缓存,避免复用损坏的缓存包 npm cache clean
- 第二步:固定触发问题的依赖版本
打开项目根目录的package.json,在devDependencies节点下手动添加一行配置,把@types/node固定到和老依赖兼容的低版本,避免npm自动拉取触发bug的高版本:
"@types/node": "6.0.0",
之后在项目根目录新建名为.npmrc的配置文件,写入以下内容,关闭npm3的自动浮动升级逻辑:
save-exact=true
- 第三步:重新执行安装
直接运行npm install即可正常完成安装,不会再触发.staging目录的ENOTDIR错误。
长期防故障方案
等本次安装成功后,立刻在项目根目录执行npm shrinkwrap命令,会生成npm-shrinkwrap.json文件,把这个文件提交到代码仓库。该文件会把所有直接、间接依赖的版本、下载地址完全锁死,后续不管上游依赖怎么更新,任何环境执行npm install都会拉取完全一致的依赖包,不会再出现这种突然安装失败的问题。
注意:生成shrinkwrap文件一定要在当前npm3环境下操作,不要用高版本npm生成,否则会出现兼容性问题导致打包流程失效。
内容的提问来源于stack exchange,提问作者Bringer
相关产品推荐
相关产品推荐

