【问题标题】:NPM Pack / Nodejitsu ignores buried Node_modules foldersNPM Pack / Nodejitsu 忽略隐藏的 Node_modules 文件夹
【发布时间】:2012-08-07 12:30:42
【问题描述】:

似乎 NPM 包,以及扩展名 nodejitsu,不喜欢我的 node_modules 文件夹。 :*(

我目前正在构建一个网络应用程序。

我的web app的项目文件夹结构如下:

Engine(folder)                      Server(folder)    readme.md     package.json

(多个文件夹)(文件夹)(文件夹)node_modules(文件夹)

                   easyimage,mongodb,mysql(folders)       socket.io (folder)

       node_modules(folder, NPM Pack ignores this)           node_modules(folder, NPM Pack ignores this)

                                                       Socket.io-client (folder, NPM Pack ignores this)

希望大家可以看看这个结构好吗!

我遇到的问题是,当我在根目录运行 NPM Pack 时,整个目录结构都被正确打包,除了第一个 node_modules 文件夹下的所有 node_modules 文件夹。

就好像 NPM 包完全忽略了那些 node_modules 文件夹。 (例如socket.io下面的那个)。

由于 NPM 包忽略了这些 npm 文件夹,jitsu 也忽略了它们,我无法启动我的网络应用程序。

如何让 NPM pack/nodejitsu 正确打包所有 node_modules 文件夹?

我当前的 package.json 文件,位于根目录,如下所示: http://pastebin.com/SAU6rwb5

如您所见,我尝试使用 bundleDependencies 告诉 NPM Pack 我正在尝试包含一些 node_modules 文件夹(模块?),但 pack 仍然忽略所有这些...另外,如果我在 "依赖项”,NPM start 在根目录创建一个新的 (??) node_modules 文件夹...但在根目录中不需要 node_modules...正如您所见,node_modules 在服务器文件夹内使用。

如何让 NPM Pack 识别所有 node_modules 文件夹中的文件和文件夹并正确打包?

【问题讨论】:

  • node_modules 不应该包含在内,因为如果您正确设置了 package.json,它可以使用 npm install 重新创建,并且在 Nodejitsu 中这将自动发生。

标签: javascript node.js npm nodejitsu


【解决方案1】:

(如果您想要一个非常简单的解决方案,请跳到最后一段)

我很难理解您的应用结构。我想我明白你想要做什么。 从 https://npmjs.org/doc/folders.html 开始,它实际上详细介绍了子模块何时以及为什么会出现或不会出现。

在本地安装时,npm 首先尝试找到合适的前缀文件夹。这样 npm install foo@1.2.3 就会安装到你的包的合理根目录下,即使你碰巧cdd到了其他文件夹。

从 $PWD 开始,npm 将遍历文件夹树检查包含 package.json 文件或 node_modules 文件夹的文件夹。如果找到了这样的东西,则将其视为有效的“当前目录”用于运行 npm 命令。 (在工作目录中运行 git 命令时,此行为受到 git 的 .git-folder 查找逻辑的启发并与之类似。)

如果没有找到包根目录,则使用当前文件夹。

当你运行 npm install foo@1.2.3 时,包会被加载到缓存中,然后解压到 ./node_modules/foo 中。然后, foo 的任何依赖项都类似地解包到 ./node_modules/foo/node_modules/....

请多多指教……

使用节点模块系统的属性处理循环,它遍历目录查找 node_modules 文件夹。 因此,在每个阶段,如果一个包已经安装在祖先 node_modules 文件夹中,那么它就不会安装在当前位置。

考虑上面的情况,foo -> bar -> baz。想象一下,如果除此之外,baz 依赖于bar,那么您将拥有:foo -> bar -> baz -> bar -> baz ...。但是,由于文件夹结构是:foo/node_modules/bar/node_modules/baz,因此无需将 bar 的另一个副本放入 .../baz/node_modules,因为当它调用 require("bar") 时,它会得到副本安装在foo/node_modules/bar

仅当完全相同的版本安装在多个嵌套的node_modules 文件夹中时才使用此快捷方式。如果两个“a”包是不同的版本,仍然有可能拥有a/node_modules/b/node_modules/a但是,如果不多次重复完全相同的包,将始终防止无限回归。

就 bundledDependencies 而言:

发布后[这也适用于打包],npm 将在 node_modules 文件夹中查找。如果 bundledDependencies 数组中没有任何项,则它们将不会包含在包 tarball 中。

我认为这意味着它将仅捆绑./node_modules/ 中列出的模块./package.json 的特定子模块。然后当然如上所述,它再次递归地遍历目录树......所以如果它在这个目录中看到另一个 package.json 文件,npm 将查看它是否有任何捆绑的 deps 包含在包中。

据我所知,由于您的基本目录中没有包,因此您在 package.json 中的捆绑依赖项不会做任何事情,而实际上在 bundledDependencies 字段中有项目确实弊大于利。

要解决此问题,您需要编辑 package.json 文件以在每个级别包含这些捆绑包。

我之前在尝试让一个打包然后解包的流星应用程序在 nodejitsu 上运行时遇到过这个问题。我以不同的方式解决了它。在我的应用程序的根文件夹中,我包含了所有顶级节点模块,并在我的 package.json 文件中明确设置了它们的版本。

据我了解,您的文件结构是这样的:

应用程序 +-- 引擎 +-- 服务器 | +-- 套接字.io | | `-- 包.json | | +-- 节点模块 `-- 自述文件.md `-- 包.json

如果是这样,那么您需要在 socket.io 下编辑 package.json 以包含您想要的捆绑的 deps。通常,尽管您可以信任软件包维护者来保留有效版本。(但在这种情况下您不能?)

至于Socket.io-client 没有被打包是因为它是socket.io 的依赖。

如果我要建议一种方法让您自己更轻松,我建议您在 MAIN 顶级 package.json 文件中包含您需要的依赖项您的应用程序@您需要的特定版本。如果您出于某种原因需要捆绑它们,请将它们添加到捆绑部分,如果您需要与作者预期不同版本的子模块。考虑创建一个名为 packagevendor 的文件夹,然后将模块放入其中,在其中您可以编辑 package.json 并将它们的依赖项捆绑到您的核心内容中。请确保不要忽略 vendorpackages 目录下带有 .npmignore.gitignore 文件的任何文件或文件夹。

或者,如果这太难了(编辑所有这些文件并指定某些版本可能会很痛苦),我建议将您的供应商包托管在可以使用脚本下载它们的地方,然后执行package.json 的postinstall 部分中的脚本(在https://npmjs.org/doc/scripts.html 阅读...您可以将其添加到您拥有“开始”脚本的同一部分中。

我希望能澄清一些事情。

【讨论】:

  • 这完全正确。谢谢 blakmatrix。我不确定为什么 mongodb/socket.io 的家伙没有在他们的 package.json 文件中包含任何捆绑的依赖项,即使他们的模块显然带有一些打包的依赖项。或者它可能已经被我的引擎预打包用于我的游戏。
  • 要尝试将我的依赖项放在根目录并将它们捆绑在那里...... require 应该抓住它们吧?
猜你喜欢
  • 2015-02-17
  • 2016-04-08
  • 2020-05-28
  • 2015-10-08
  • 2018-01-12
  • 1970-01-01
  • 2019-01-09
  • 2015-07-01
  • 1970-01-01
相关资源
最近更新 更多