Node npm在Windows中的文件路径太长,无法安装软件包。

91

情况

我想在Windows主机的开发环境中使用gulp和相关的前端工具链。我试图使用像Browser-Sync这样的gulp插件时遇到了问题,因为node_modules文件夹图形展开,使得Windows文件路径太长而无法复制文件。我希望有一个务实的方法来解决这个问题,不考虑Node社区未来是否会提供改进npm在Windows上可用性的方案。

2个问题

  1. 是否有适用于Windows的npm工作流程只需"运行命令,文件安装完成"即可(例如与OSX上的npm、Linux上的npm、Ruby Gems甚至Nuget相当)?我不想每次在Windows上使用npm时都要动手编辑一堆文件、符号链接等。

  2. 是否有一个经过充分文档化并且稳定的Cygwin工作流程,可绕过Windows API文件路径限制进行npm和node执行操作?

以下是详细信息...

通用问题

  • 从标准的Windows命令提示符中运行npm install,在深度嵌套的node_modules层次结构中失败。
  • 根据Joyent的github存储库线程,这是一个公认的问题,没有可接受的解决方案供Windows环境下的开发人员使用。(真的吗?)
  • NT内核支持长达32,767个字符的文件路径长度。
  • Windows API的MAXPATH限制为260个字符。
  • Windows API处理所有主要的Windows shell和诸如Explorer、CMD、Powershell、MYSgit bash等文件操作。(MS真的吗?NTFS已经存在多久了?)
  • Cygwin支持长文件路径,但npm.cmd无法直接使用,因为换行符格式不正确。我尝试对npm进行DOS2Unix转换以使其与Cygwin配合使用,但好像还有其他问题。

我目前的技巧

  • 在C:\根目录下创建一个名为“n”的文件夹作为暂存区,这可以缩短文件路径。
  • 在“n”文件夹内运行npm以安装所需模块。
  • 启动Cygwin并使用cp命令将node_modules文件夹复制到目标项目中。
  • 当依赖项更改或需要启动新项目时,请重复上述步骤。

其他不可取的解决方案

符号链接可用于缩短文件路径,但这些是笨拙的解决方案。随着npm生态系统的增长,嵌套的依赖链会变得过长,使得这种解决方案变得难以使用。

将所有依赖项添加到根文件夹的package.json文件中在我看到的一个帖子中提到。虽然这种方法会扁平化文件结构并防止加载重复的模块,但这种解决方案感觉很不自然。它还会破坏npm的可用性、耐久性和生产力,因为您必须在安装后手动或使用一些笨拙的脚本来处理文件和文件夹。这种方法也容易受到符号链接方法可能最终遭受的同样命运的影响。


我差点以为我已经解决了这个问题。我通过在以下两个文件上运行dos2unix实用程序来让Cygwin与npm配合使用:npm.cmd和npm。 - Allan McLemore
Windows API路径限制使得npm无法使用,因为一些npm模块使用Visual Studio来构建文件。这是我在npm Browser-Sync时收到的错误信息:C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(301,5): error MSB3491: 无法将行写入文件“Release\obj\validation\validation.tlog\validation.lastbuildstate”。指定的路径、文件名或两者都太长了。完全限定的文件名必须少于260个字符,目录名必须少于248个字符。 - Allan McLemore
我在Windows上使用npm加载节点模块时,可能会采用“拉夫子糖”式的方法。这涉及到几轮以下操作:npm install、npm dedupe、npm shrink和rm -r node_modules。重复执行此操作似乎可以在一定程度上解决长文件路径问题,但这有点像拉夫子糖(例如,直到完成才算完成)。是否有人将其编码或编写了自动化工具,使其更易于使用? - Allan McLemore
谢谢。我会尝试使用fenestrate。我并没有在这篇帖子上看到太多的意见,而且它已经快两周了。猜想对于Windows节点开发来说,260个字符的文件路径限制暂时只会是一个挑战,缺乏官方的工作流指导。 - Allan McLemore
2
@yoneal 为了个人使用并快速入门,fenestrate 应该递归地遍历你的 node_modules 文件夹,因此你不需要在深层依赖上手动运行它。然而,如果能够 fork 这些依赖项就更好了——我认为有很多带有简单 fenestrate 配置的 forked 模块会向 npm 维护者发送积极的信息。 - zetlen
显示剩余2条评论
9个回答

58

从npm版本3.x开始,Windows上深度嵌套文件夹的问题大多已经解决。

根据npm的说法:

.npm@3通过将尽可能多的内容提升到顶层node_modules,使安装“最大化扁平化”。这意味着只有在冲突时才会发生嵌套,因此树不应该很深。因此,不应该遇到Windows路径长度限制的问题。

我刚刚安装了npm 3.1.0并在一个导致出现可怕的The specified path, file name, or both are too long错误的包上试用了一下。

问题消失了。

您可以从这里获取最新的npm构建:npm releases


4
我在Windows机器上成功升级了npm 3.x版本。不好意思打个广告:我写了一篇有关Windows用户的npm 3文章,链接是http://www.triplet.fi/blog/npm-3-will-bring-brighter-future-for-windows-users/。 - Tx3

24

Windows 8.1和10有一个选项可以增加Win32路径限制:

  • 打开组策略编辑器(按下Windows+R,输入gpedit.msc并按Enter)
  • 导航到以下目录:本地计算机策略\计算机配置\管理模板\系统\文件系统
  • 双击启用Win32长路径选项并启用它。

输入图像描述


选项对我不可用,顺便说一下,我是从Win 7 Pro升级的,这可能是一个可能的原因。 - Evan Morrison
@EvanMorrison,“Filesystem\NTFS\Enable NTFS long paths”在后来的Win10版本中更名为“FileSystem\Enable Win32 long paths”。我已更新答案以供参考。 - Marcelo Mason
1
Win Server 2012 R2 有什么想法吗? - sairfan
根据 https://superuser.com/questions/1528789/windows-server-2012-r2-standard-enable-ntfs-long-paths-policy-option-missing,很遗憾无法实现。 - ihebiheb

12

这是一种解决方法。

有些节点模块可以为您扁平化依赖项。
链接在这里:

这些模块所做的事情也可以手动完成。目前唯一真正的解决方案是将所有模块放置在单个级别上,并彼此引用,而不是私有地嵌套它们的依赖项副本。


10
我认为flatten-packages文档详细且易于使用。 - StriplingWarrior
上面npm-dedupe的链接已经失效了。我在这里找到了当前存在的链接:https://docs.npmjs.com/cli/v8/commands/npm-dedupe - Arsen Khachaturyan

3

Allan -

从您提供的GitHub问题中,npm将默认添加dedupe-at-install-time。这比Node的模块系统更可行,但仍然不是很简单,并涉及重新设计一些长期存在的模式。

目前,npm正在进行此项工作,被称为multi-stage-install,并针对npm@3。npm开发负责人Forrest Norvell将在新的一年里花时间在Windows上运行,因此请在npm问题跟踪器上创建与Windows相关的问题 < https://github.com/npm/npm/issues >


3
我有同样的问题。扁平化依赖关系并不是完整的解决方案,因为您可能正在使用依赖于不同版本相同依赖模块的模块。我发现在扁平化之后,gulp-run 模块停止工作(我怀疑这与模块对 bin/.bin 目录的假设有关)。 真遗憾!讨论这个问题的文章很多,但是没有看到解决方案: https://github.com/joyent/node/issues/6960

https://github.com/npm/npm/issues/3697

一个对我有效的解决方法是手动添加项目不需要的依赖项。
如果您想确定哪些软件包正在给您带来问题,我发现PathLengthChecker非常有用。只需提取EXE并运行GUI或命令行应用程序即可。另一种发现问题的方法是尝试在Visual Studio中构建,但它会失败,而不告诉您哪个目录名称太长。
这是我的解决方法的命令行示例:
mkdir c:\reallylongdirectorywillbreakinwindows
cd c:\reallylongdirectorywillbreakinwindows
npm init
npm install --save-dev grunt-bower-task
PathLengthChecker.exe RootDirectory="C:\reallylongdirectorywillbreakinwindows" MinLength=260

我得到了以下结果:

261: C:\reallylongdirectorywillbreakinwindows\node_modules\grunt-bower-task\node_modules\bower\node_modules\update-notifier\node_modules\latest-version\node_modules\package-json\no de_modules\registry-url\node_modules\npmconf\node_modules\config-chain\readme.markdown

[剪辑 - 总共有12个]

根据npm ls命令:
└─┬ grunt-bower-task@0.4.0
  ├── async@0.1.22
  ├─┬ bower@1.3.12
  │ ├─┬ update-notifier@0.2.0
  │ │ ├─┬ latest-version@0.2.0
  │ │ │ └─┬ package-json@0.2.0
  │ │ │   └─┬ registry-url@0.1.1
  │ │ │     └─┬ npmconf@2.1.1
  │ │ │       ├─┬ once@1.3.1
  │ │ │       │ └── wrappy@1.0.1

让我们使用npmconf - 它是所有导致问题的超长文件的容器。我们需要npmconf 2.1.1。

npm install --save-dev npmconf@2.1.1
(now delete the node_modules directory - you may have to use Windows Explorer if you can't do it with rmdir /s)
npm install
PathLengthChecker.exe RootDirectory="C:\reallylongdirectorywillbreakinwindows" MinLength=260

没有结果 - 所有的文件都在限制范围内!

显而易见的警告是,它只能在每个包中工作一次 - 对同一模块不同版本的依赖关系不能在根节点_modules级别安装,因为node没有考虑目录结构中的版本问题。

这种解决方法并不完美,但它解决了我使用Windows时的主要目标,而且由于分辨率在package.json中正确,所以这种解决方法适用于其他开发者和构建服务器,而无需进行任何手动或全局操作。


2
如果您愿意全局安装,这可能是一种解决方法:
您可以调整npm安装全局模块的路径为非常短的路径(通常为:c:\users\\{username}\AppData\Roaming\npm\npm_modules),这已经占用了很多字符。
要进行调整,请参见此处:更改Windows中node.js模块的默认全局安装目录? 如果将其调整为例如c:\n\,在某些情况下可能会解决问题。

1

这是最终解决我的方法...

安装gulp后收到错误信息时,运行... gulp

如果您看到某个软件包失败,请使用--no-bin-link手动安装。

sudo npm install {package} --no-bin-link

其中{package}是出现问题的软件包。

在这之后,我收到了一个关于插件“gulp-notify”的错误消息:未找到:notify-send。

这是由于Vagrant的插件问题所致。您可以关闭通知..

export DISABLE_NOTIFIER=true;

或者使用Vagrant插件进行安装。

祝你好运。即使在遵循了许多人的建议之后,我也花了很长时间。

Brandon


0

npm install --no-bin-link。这样你将会得到一个完整扁平化的node_modules


0

在Windows系统中:

  1. 使用Windows资源管理器,导航到您的Vagrant共享文件夹(我正在使用Scotchbox),例如:C:\scotchbox/public/gulpProject
  2. 在文件夹的地址栏中键入cmd并按Enter
  3. 进行Gulp安装:npm install

1
请勿复制粘贴相同的答案。应该标记为重复。此外,请不要在您的帖子中使用脏话。 - Tunaki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接