如何修复现有文件和符号链接之间的 npm install 冲突?

Clo*_*omp 5 continuous-integration npm devops

我遇到了NPM问题,它似乎正在检测现有文件和符号链接之间的冲突,同名。ls -l从项目的根文件夹运行时,我看不到任何符号链接。我如何弄清楚 NPM 发生了什么并解决这个冲突?

持续集成构建服务器正在运行:Node.js 4.4.3 = 最新的 LTS 构建。

由于此警告,我的 localhost Node 5.x 框切换到使用 phantomjs-prebuilt ......所以从 4.4.3 -> 5.10.1 更新 Node 服务器版本不是问题,也不是正确的修复:

npm WARN deprecated phantomjs@2.1.7: Package renamed to phantomjs-prebuilt. Please update 'phantomjs' package references to 'phantomjs-prebuilt'
Run Code Online (Sandbox Code Playgroud)

我的任何 *.js 代码中都没有这些,所以我不知道这是从哪里需要的,也不知道为什么:

require("phantomjs") 
require("phantomjs-prebuilt")
Run Code Online (Sandbox Code Playgroud)

Google & SO上搜索这个短语,没有产生足够有用的结果来解决我的问题:

"npm ERR! EEXIST: file already exists, symlink"
Run Code Online (Sandbox Code Playgroud)

这是我已经尝试运行的:

npm uninstall -g phantomjs
npm WARN not installed in /.../.nvm/versions/node/v4/lib/node_modules: "phantomjs"

rm -rf node_modules // to delete that folder
npm install

npm ERR! EEXIST: file already exists, symlink '../phantomjs-prebuilt/bin/phantomjs' -> '/.../node_modules/.bin/phantomjs'
File exists: ../phantomjs-prebuilt/bin/phantomjs
Move it away, and try again.
Run Code Online (Sandbox Code Playgroud)

使用 Google 在网络上找到了此错误的屏幕截图。滚动到CI 服务器代码示例的底部。(注意:这是别人的截图,但看起来和我的很相似。)

使用npm listnpm ls显示 phantomjs 已安装:

??? phantomjs@2.1.7
Run Code Online (Sandbox Code Playgroud)

使用npm ls -g显示一个空白列表。我认为这意味着没有任何包,也没有安装到全局区域的符号链接。

我尝试使用以下方法卸载 phantomjs:

npm uninstall -g phantomjs
npm WARN not installed in /.../.nvm/versions/node/v4/lib/node_modules: "phantomjs"
Run Code Online (Sandbox Code Playgroud)

我也尝试使用wilmore在这个Homebrew 上的回答中的想法- 重复的“链接”错误。这里的根本问题是什么?题:

brew link --overwrite phantomjs
Warning: Already linked: /usr/local/homebrew/Cellar/phantomjs/2.1.1
To relink: brew unlink phantomjs && brew link phantomjs
Run Code Online (Sandbox Code Playgroud)

这让我从最后一行中选择了第一个选项:

brew unlink phantomjs
Unlinking /usr/local/homebrew/Cellar/phantomjs/2.1.1... 2 symlinks removed
Run Code Online (Sandbox Code Playgroud)

当我重新运行时:

npm install
Run Code Online (Sandbox Code Playgroud)

它仍然会因为这个错误而跳闸:

npm ERR! EEXIST: file already exists, symlink '../phantomjs-prebuilt/bin/phantomjs' -> '/.../node_modules/.bin/phantomjs'
File exists: ../phantomjs-prebuilt/bin/phantomjs
Move it away, and try again.
Run Code Online (Sandbox Code Playgroud)

如何进一步调试符号链接并修复npm install现有文件和符号链接之间的冲突?

Clo*_*omp 5

在写完这个问题并尝试重新创建这个问题后,我才想通了,以便其他人可以调试它。所以这里是如何修复这个边缘情况错误,以防将来有人遇到它。

我只是从我的 package.json 文件中删除了这两个文件,然后重新运行npm install看看会发生什么。然后将它们检查到 CI 服务器中,我可以看到它在做什么。我不得不重新添加第一个“phantomjs”行来让 CI 服务器通过它的测试。这是“phantomjs-prebuilt”行,必须删除。

注释解释了哪些应该与 Node.js 的 4.x 和 5.x 版本一起使用:

"phantomjs": "^2.1.3", // Leave this in for Node 4.x LTS, remove it with 5.x+
"phantomjs-prebuilt": "^2.1.7", // Removed this with 4.x LTS, but use it with 5.x+
Run Code Online (Sandbox Code Playgroud)

这就是修复 CI 服务器并允许测试通过的原因!:)

最初,我一直在使用 Node 5.6.0(安装于 2016 年 2 月)并且一直在尝试更新一些 Gulp 任务以使用现有的 Node 4.4.3 LTS CI 服务器。

Gulp 在使用 5.6.0 时一直抱怨 phantomJS,所以我同时安装了phantomjs& phantomjs-prebuiltwith--save-dev来让它停止引起问题。然后从 Node 5.6.0 降级到 4.4.3 LTS 以调试 CI 服务器,会抛出符号链接错误(在我上面的问题中提到)。

因此,如果npm ERR! EEXIST:将来有人遇到此问题,请尝试从 package.json 文件中删除对 npm 模块的所有引用(错误涉及到该模块)。如果您的 CI 服务器需要它们,然后将它们 1 对 1 重新添加。

符号链接将存在于 /node_modules/ 文件夹中的某处。我的 /node_modules/ 文件夹有 885 个子文件夹!我无法深入研究所有这些,试图找出较低级别的符号链接出了什么问题。

但是,如果有人对如何调试符号链接有任何好的建议,我很想了解更多关于它们的信息。我会赞成好的答案,因为ls -l symlinks不存在易于使用的东西。