题 如何在Windows上部署具有深度node_modules结构的Node.js应用程序?


我遇到了一个奇怪的问题 - 显然有些Node.js模块有这样的问题  文件夹层次结构 Windows复制命令(或PowerShell的 Copy-Item 这是我们实际使用的)当路径超过250个字符时,会遇到臭名昭着的“路径太长”错误。

例如,这是单个Node模块可以创建的文件夹层次结构:

node_modules\nodemailer\node_modules\simplesmtp\node_modules\
xoauth2\node_modules\request\node_modules\form-data\node_modules\
combined-stream\node_modules\delayed-stream\...

看起来很疯狂,但Node模块却是现实。

我们需要在部署期间使用复制粘贴(我们不使用像Heroku这样的“聪明”目标平台,Git部署可能是一个选项),这是对Windows的严重限制。

是不是有一个npm命令或什么会压缩 node_modules 文件夹或者可能只包含运行时实际需要的内容? (节点模块通常包含 test 我们不需要部署的文件夹等。)任何其他想法如何解决它?遗憾的是,不使用Windows不是一个选项:)


90
2017-11-10 01:32


起源


你的项目有没有 package.json同 dependencies 组?如果是这样,你可以不用复制 node_modules 并使用npm来 install 要么 update 依赖? - Jonathan Lonowski
@JonathanLonowski我们的部署环境不支持执行 npm install 在目标环境中,它通过在本地创建“部署包”(基本上是ZIP加上一些元数据)来工作,然后将其上传到目标计算机,在那里提取,就是这样。所以我需要包括 node_modules 直。 - Borek Bernard


答案:


npm v3(最近发布)通过扁平化依赖关系解决了这个问题。请查看此处的发行说明 https://github.com/npm/npm/releases/tag/v3.0.0 下 flat flat 部分。

关于这个问题的最后评论 https://github.com/npm/npm/issues/3697


23
2017-07-07 11:14



发布说明 flat flat 现在埋在另一页。这是一个直接链接: github.com/npm/npm/releases/tag/v3.0.0 - John-Philip
谢谢@ John-Philip,用新链接更新了答案 - RameshVel


只是为了增加这个...帮助我的另一件事是列出所有已安装的模块 npm ls

这将为您提供一个模块和版本的树...从那里很容易识别哪些是重复的... npm dedupe 没有为我做任何事。我不确定这是一个错误还是什么(Node v 10.16)

因此,一旦确定了重复模块,请使用以下命令将其安装到根node_module目录中 npm install dupemodule@1.2.3 --save-dev版本很重要。

之后,我清除了我的node_modules目录并重新开始 npm install

简洁版本

  1. npm ls 获取所有已安装模块的列表。
  2. 查看这些模块并识别重复的模块(版本很重要
  3. npm install module@version --save-dev 在根node_modules目录中安装这些模块并更新package.json。
  4. rmdir node_modules 删除node_modules目录。
  5. npm install 下拉依赖项的新副本。

一旦我这样做,一切都更清洁。

我还建议您对package.json文件进行注释,以显示哪些文件被压缩以展平node_modules树。


62
2017-08-27 18:32



+1,希望我能两次投票! - Davin Tryon
这对我很有用。谢谢!原谅我的无知,但为什么模块不总是安装在顶层? - Caleb
@Caleb可能是因为不同的模块依赖于同一模块的不同版本,或者可能只是因为它更容易获得所需的任何东西, 然后 把它考虑下来......我不知道。 - Ben Lesh
无论如何,谢谢你的提示。我刚从项目中删除了大约1700个重复文件。删除东西是我最喜欢的开发人员!另外,对于任何想要如何向package.json添加注释的人来说,这是你的答案: stackoverflow.com/questions/14221579/... - Caleb
github.com/joyent/node/issues/6960  节点家伙说Windows是一流的公民。他们说。但他们关闭了这个问题而没有解决问题。幸运的Windows用户。 - vee


考虑到你的限制,我认为没有任何好的解决方案,但这里有一些可能有用的东西。

  • 尝试使用 npm dedupe 优化您的目录层次结构可能会缩短某些路径
  • 使用 npm install --production 没有开发工具安装
  • 采取一些深层嵌套的依赖项(足以避免问题,我建议)并将它们移动到顶级node_modules目录。只需跟踪它们就可以了解哪些是您真正的依赖项,哪些是此问题的解决方法。
  • 或者将一些深度依赖项移到最高位置 node_modules 目录下 your_project/node_modules/pkg_with_deep_deps 这将允许他们有足够短的路径,但仍然有效。所以这就是 your_project/node_modules/pkg_with_deep_deps/node_modules
    • 我认为 require 应该能够在运行时正确找到它们。您只需要清楚地记录您手动更改的内容,为什么要这样做,并保持您自己的真实依赖关系准确地表示在 package.json

这是一个github问题讨论 详细阐述了这个问题。


38
2017-11-10 02:39



谢谢你指出 dedupe (根本不知道)和 --production (npm install -h 没有显示这个选项)!遗憾的是,使用ZIP存档不是一种选择,请参阅上面的评论。 - Borek Bernard
npm重复数据删除只会将“常用”模块展平到层次结构中的最低公共位置。还不够好。一个适当的解决方案将允许“强制平坦”整个层次结构,并可能允许忽略test / doc目录。另一种方法是节点直接从tar文件支持读取模块。 - MMind
同意,包的某种“二进制”分布(ZIP,tarball,等等)将非常有用。 - Borek Bernard


我编写了一个名为“npm-flatten”的节点模块,它可以在这里平衡你的依赖关系: https://www.npmjs.org/package/npm-flatten

如果您正在寻找distrubtion,我还编写了一个NuGet包,它将在这里将完整的node.js环境与您的.NET项目集成: http://www.nuget.org/packages/NodeEnv/

反馈将是受欢迎的。


11
2018-05-04 19:28



这对我们有用。当我们首先运行nmp重复数据删除时,我们得到了更好的结果。 - Shaun Rowan


帮助我的一点是将本地驱动器映射到我的Node.js文件夹:

net use n:\ computername \ c $ \ users \ myname \ documents \ node.js / persistent:yes

之前:c:\ users \ myname \ documents \ node.js \ projectname(45个字符) 之后:n:\ projectname(14个字符,少31个字符)

在许多情况下,这允许安装一些模块。

我会说当我尝试将所有代码备份到USB驱动器时,我刚刚重新发现了这个问题。

“C:\用户\ MYNAME \文件\ Node.js的\角phonecat \ node_modules \因缘\ node_modules \ chokidar \ node_modules \ anymatch \ node_modules \ micromatch \ node_modules \正则表达式缓存\ node_modules \基准\ node_modules \文件阅读器\ node_modules \ extend-shallow \ benchmark / fixtures太长了。“

即使我试图使用N:驱动器盘符来支持它们,在某些情况下由于路径长度仍然失败但是它足以修复上面的那个。


1
2018-05-05 02:12



令人惊讶的是,这个问题仍未解决我的Node / MS .. - Borek Bernard


1)在发布版本期间,您可以通过设置文件夹属性来阻止Visual Studio扫描这些文件/文件夹 作为隐藏文件夹 (只需将其设置为node_modules)。 参考: http://issues.umbraco.org/issue/U4-6219#comment=67-19103

2)您可以通过在CsProject文件中包含以下XML节点来排除在打包期间发布的文件或文件夹。

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
  ...
  <OutputPath>bin\</OutputPath>
   <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
  <ExcludeFilesFromDeployment>File1.aspx;File2.aspx</ExcludeFilesFromDeployment>
  <ExcludeFoldersFromDeployment>Folder1;Folder2</ExcludeFoldersFromDeployment>
</PropertyGroup>

1
2017-10-12 19:38





我发现了一个解决方案 Microsoft Node.js指南

  • 从短路径开始(例如c:\ src)
  • > npm install -g rimraf 删除超过的文件 max_path
  • > npm dedupe 将重复的包移动到顶级
  • > npm install -g flatten-packages 将所有包移动到顶级,但可能导致版本问题
  • 升级到 npm@3 试图制造的 node_modules 文件夹heirarchy最大平。
    • 使用Node v5发货
    • 要么… > npm install –g npm-windows-upgrade

1
2017-11-16 12:10





这不是一个合适的解决方案,而是在你匆忙时解决,但你可以使用 的7-Zip 压缩文件夹,移动压缩文件并解压缩没有任何问题。

我们使用该解决方案来部署Node.js应用程序,在该应用程序中无法进行干净的npm安装。


0
2017-10-08 15:51



是的。这是我每次需要安装mongoose时所做的事情。它有本机代码,我有多个/更新版本的Visual Studio =失败。我可以打开VS,引入每个失败的.sln文件并重建它。但是根据需要在整个node_modules \ mongoose folderset上单独使用XCOPY会更容易(当然看版本)。 - Michael Blankenship