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

91

我遇到了一个奇怪的问题 - 显然一些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文件夹,或者只包含运行时实际所需的内容吗? (Node模块通常包含不需要部署的test文件夹等。)是否有任何其他方法可以解决这个问题?不幸的是,不能不使用Windows :)


1
你的项目是否有一个设置了 dependenciespackage.json 文件?如果是这样,你可以将其复制并排除 node_modules 文件夹,然后使用 npm 命令来进行依赖项的 installupdate - Jonathan Lonowski
4
我们的部署环境不支持在目标环境中执行 npm install,它通过在本地创建一个“部署包”(基本上是一个ZIP文件加一些元数据),然后将其上传到目标机器,在那里进行提取,这样就完成了。所以我需要直接包含 node_modules - Borek Bernard
8个回答

62

补充一点...另一件帮助我的事情是使用 npm ls 列出所有已安装的模块。

这将给您提供一个模块版本树... 从那里很容易识别哪些是重复的... npm dedupe 对我没有任何作用。我不确定这是否是一个错误或其他什么问题(Node v 10.16)。

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

之后,我清空了我的 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 树扁平化。


这对我非常有效。谢谢!请原谅我的无知,但为什么模块不总是安装在顶层? - Caleb
2
@Caleb 可能是因为不同的模块依赖于同一模块的不同版本,或者只是因为先获取所需的所有内容,然后再进行因素分解更容易...我不知道。 - Ben Lesh
7
无论如何,感谢这个提示。我刚刚从我们的项目中删除了大约1700个重复文件。删除东西是我作为开发人员最喜欢的部分!此外,对于任何想了解如何向package.json添加注释的人,这里有你的答案:https://dev59.com/DGYq5IYBdhLWcg3wwDRA - Caleb
Node.js的开发者表示Windows是一等公民。他们说。 但是他们关闭了这个问题,什么都没有解决。 幸运的Windows用户。 - vee

38

考虑到你的限制条件,我认为没有太好的解决方案,但以下几点可能会有所帮助。

  • 尝试使用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 问题。


感谢指出dedupe(我完全不知道)和--productionnpm install -h没有显示此选项)!不幸的是,使用ZIP存档不是一个选择,可以看到上面的评论。 - Borek Bernard
9
npm dedupe只会将“常见”模块平铺到层次结构中的最低公共位置。这还不够好。一个正确的解决方案应该允许“强制平面化”整个层次结构,并可能允许忽略测试/文档目录。另一种替代方法是让node直接从tar文件中读取模块。 - MMind
3
同意,某种“二进制”软件包的发布(ZIP、tarball或其他格式)将非常有用。 - Borek Bernard

24

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

11

这对我们很有效。当我们首先运行nmp dedup时,我们获得了更好的结果。 - Shaun Rowan

1

1) 在发布构建期间,您可以通过将文件夹属性设置为隐藏文件夹(只需将其设置为node_modules)来防止Visual Studio扫描这些文件/文件夹。 参考: 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

有一件事帮助了我,那就是将本地驱动器映射到我的Node.js文件夹:

net use n: \计算机名\c$\users\我的用户名\documents\node.js /persistent:yes

之前:c:\users\我的用户名\documents\node.js\项目名称(45个字符) 之后:n:\项目名称(14个字符,少了31个字符)

在许多情况下,这可以安装某些模块。

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

"C:\Users\我的用户名\Documents\Node.js\angular-phonecat\node_modules\karma\node_modules\chokidar\node_modules\anymatch\node_modules\micromatch\node_modules\regex-cache\node_modules\benchmarked\node_modules\file-reader\node_modules\extend-shallow\benchmark\fixtures太长了。"

即使我尝试使用N:驱动器号备份它们,在某些情况下仍然会由于路径长度而失败,但它足以修复上面的问题。


1

我在Microsoft Node.js Guidelines中找到了一个解决方案。

  • 从较短的路径开始(例如c:\src)
  • > npm install -g rimraf 删除超过max_path的文件
  • > npm dedupe 将重复的包移动到顶层
  • > npm install -g flatten-packages 将所有包移动到顶层,但可能会导致版本问题
  • 升级到npm@3,它试图使node_modules文件夹的层次结构最大化扁平化。
    • 随Node v5一起发布
    • 或… > npm install –g npm-windows-upgrade

0

这不是一个正式的解决方案,而是在你急需时的权宜之计,但你可以使用 7-Zip 来压缩你的文件夹,移动已压缩的文件并无误地解压。

我们曾经在部署 Node.js 应用程序时使用过该解决方案,因为无法进行干净的 npm 安装。


是的。每次我需要安装mongoose时,这就是我所做的。它里面有本地代码,而且我有多个/更新版本的Visual Studio = 失败。我可以打开VS,将每个失败的.sln文件带入并重新构建它。但只需根据需要复制整个node_modules\mongoose文件夹集(当然要注意版本),这样更容易。 - Michael Blankenship

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