节点 npm windows 文件路径太长,无法安装软件包

情况

我想在 Windows 托管的开发环境中使用 Gulp 和相关的前端工具链。我在尝试使用像 Browser-Sync 这样的集成插件时遇到了瓶颈,因为 node _ module 文件夹曲线使得 windows 文件路径太长,无法复制文件。不管 Node 社区未来可能提供或不可能提供什么来改善 Windows 上的 npm 可用性,我现在希望在 Windows 上采用一种务实的方法来处理这个问题。

2个问题

  1. 是否有一个用于 Windows 的 npm 工作流程,只是按照预期的方式工作?“ run the command and the files install”(比如在 OSX 上的 npm,Linux 上的 npm,ruby gems,甚至是 nuget)我不想每次在 Windows 上使用 npm 时都要做一大堆手动文件编辑、符号链接等工作。

  2. 是否有一个良好的文档,稳定的 Cygwin 工作流程,用于 npm 和节点执行,以解决 Windows API 文件路径的限制?

血淋淋的细节如下..。

一般问题

  • 从标准命令提示符运行 npm 安装会在深度嵌套的 node _ module 层次结构中失败。
  • 根据 Joyent 的 github repo 线程,在以 Windows 为中心的环境中没有适合开发人员的变通方法的 这是一个公认的问题(真的吗?)
  • NT 内核支持的文件路径长度最高可达32,767个字符。
  • WindowsAPI 的 MAXPATH 限制为260个字符。
  • Windows API 处理所有主要 Windows shell 的文件操作,包括: Explorer、 CMD、 Powershell、 MYsgit bash 等(MS 真的吗? NTFS 已经存在多久了?)
  • Cygwin 支持长文件路径,但是由于 crlf 格式,npm.cmd 不能立即工作。我在 npm 上尝试了 DOS2Unix 转换,使其能够与 Cygwin 一起工作,但似乎还有其他问题。

我的现代黑客

  • 在 C: 的根目录中创建一个“ n”文件夹作为临时区域,因为 这缩短了我的文件夹路径。
  • 在“ n”文件夹中运行 npm 来安装任何我需要的模块。
  • 启动 Cygwin 并使用 cp 将 node _ module 文件夹复制到目标项目中。
  • 当依赖关系发生变化或者需要启动一个新项目时,清洗并重复执行。

其他令人不快的解决方法

可以使用符号链接 来缩短文件路径,但这些都是笨拙的技巧。随着 npm 生态系统的增长,嵌套的依赖链将变得太长,这个解决方案将变得不可用。

在我碰到的一个线程中提到过将 ALL 依赖项添加到根文件夹的 package.json 文件中。虽然这种方法将使文件夹结构变得平坦,并防止加载重复的模块,但是这种解决方案让人感觉不自然。它还扼杀了 npm 的可用性、持久性和生产力,因为您必须在安装后手动或使用一些蹩脚的脚本处理文件和文件夹。这种方法也很容易遭受符号链接方法最终可能遭受的同样命运。

48316 次浏览

This is a work around solution.

There are some node modules that flattens your dependencies for you.
Links are here:

What these modules are doing can be done manually as well. This is the only real solution exists as of now, i.e to have all your modules at a single level, requiring each other, instead of all having private copies of their dependencies nested deeply.

Allan -

From the github issue you linked,

npm will add dedupe-at-install-time by default. This is significantly more feasible than Node's module system changing, but it is still not exactly trivial, and involves a lot of reworking of some long-entrenched patterns.

This is (finally) currently in the works at npm, going by the name multi-stage-install, and is targeted for npm@3. npm development lead Forrest Norvell is going to spend some time running on Windows in the new year, so please do create windows-related issues on the npm issue tracker < https://github.com/npm/npm/issues >

This is what finally fixed it for me...

After installing gulp and receiving errors, run... gulp

When you see a package failing, install it manually with --no-bin-link.

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

Where {package} is the package that is having problems.

After all of this I was receiving an Error in plugin 'gulp-notify' Message: not found: notify-send.

This was due to a plugin issue with Vagrant. You can either turn off notifications..

export DISABLE_NOTIFIER=true;

Or install the plugin with Vagrant.

Best of luck.. I spent a long time on this, even after following a lot of people's recommendations.

Brandon

I have the same issue. Flattening the dependencies isn't a complete solution, since you might be using modules that depend on different versions of the same dependent module. I discovered the gulp-run module stopped working after flattening (related to module assumptions about bin/.bin directories, I suspect). Drat!

There's lots of discussion about the problem, but no solution in sight: https://github.com/joyent/node/issues/6960

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

A workaround that's working for me is to manually add dependencies my project doesn't explicitly need.

If you want to identify which packages are giving you problems, I found PathLengthChecker quite useful. Just extract the EXE and run the GUI or command line app. The other way I've uncovered the problem is to try to build in Visual Studio, but it fails without telling you which directory name is too long.

Here's a command line example of my workaround:

mkdir c:\reallylongdirectorywillbreakinwindows
cd c:\reallylongdirectorywillbreakinwindows
npm init
npm install --save-dev grunt-bower-task
PathLengthChecker.exe RootDirectory="C:\reallylongdirectorywillbreakinwindows" MinLength=260

I got back:

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

[snip - there were 12 of them]

According to the npm ls command:

└─┬ 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

Let's go with npmconf - it's the container for all the over-length files that are causing issues. We need 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

No results - all files are within limits!

The obvious caveat here is that it only works once per package - dependencies on different versions of the same module can't be installed at the root node_modules level because node doesn't account for versions in the directory structure.

This workaround isn't perfect, but it solves my main goals of having node work on Windows, and since the resolution is right in package.json, the workaround works for other developers and build servers without any manual or global fussing.

The problem with deeply nested folders on Windows has been mostly solved starting with npm version 3.x.

According to npm:

.npm@3 makes the install "maximally flat" by hoisting everything it can to the top level node_modules. This means nesting only occurs on conflicts and as such, trees should never get very deep. As such, the windows path length limitation shouldn't be run into.

I have just installed npm 3.1.0 and tried it out on a package that was throwing the dreaded The specified path, file name, or both are too long error.

The problem went away.

You can get the latest npm builds from here : npm releases

If you are OK with installing it globally this could be a work-around:

You can adjust the path where npm is installing the global modules to something very short (usually it is: c:\users\\{username}\AppData\Roaming\npm\npm_modules) which already takes a lot of characters.

To adjust it see here: Change default global installation directory for node.js modules in Windows?

If you adjust it to, e.g., c:\n\ in some cases it might solve the issue.

In windows:

  1. Using your windows explorer, Navigate to your vagrant shared folder (I am using scotchbox by the way) e.g C:\scotchbox/public/gulpProject
  2. In the address bar of the folder, type cmd and press Enter
  3. Do your gulp installation npm install

npm install --no-bin-link. You will have a entire flattened node_modules

Windows 8.1 and 10 have an option to increase the Win32 path limit:

  • Open Group Policy Editor (Press Windows+R and type gpedit.msc and hit Enter)
  • Navigate to the following directory: Local Computer Policy\Computer Configuration\Administrative Templates\System\Filesystem
  • Doubleclick on Enable Win32 long paths option and enable it.

enter image description here