需要依赖节点模块中的另一个依赖项

Posted

技术标签:

【中文标题】需要依赖节点模块中的另一个依赖项【英文标题】:Require dependency of another dependency in node modules 【发布时间】:2012-04-01 22:50:29 【问题描述】:

我有一个简单的节点应用程序,它依赖于 github 上的另一个应用程序。使用npm install 可以很好地安装依赖项,但是当我尝试要求在那里安装一些东西时,它说它不可用。例如,github 应用程序将 Mongoose 作为依赖项安装。我认为这个父应用程序将能够访问该模块,因为它是在一个孩子:

var mongoose = require('mongoose')

结构看起来像这样:

/app
  /node_modules
    /github_dependency [parent module]
      /node_modules
        /mongoose [child module]

我是否只需要在父应用程序中也包含 mongoose 作为依赖项,还是有办法通过子应用程序访问该模块?

【问题讨论】:

【参考方案1】:

我是否只需要在父应用程序中也包含 mongoose 作为依赖项,还是有办法通过子应用程序访问该模块?

虽然 可能 你可以require('github/node_modules/mongoose'),标准做法是显式安装所有依赖项(即,您应该将 mongoose 作为应用程序的依赖项)和 require('mongoose')

【讨论】:

谢谢,我们会遵守这个约定。我确实想提一件事,理论上这会导致项目中存在多个重复的依赖项吗? 它可以,并且您通常会在节点项目中拥有多个不同模块(及其版本)的多个实例。这是 npm IMO 的优势之一,在 00 年代的大部分时间里,他们都在研究不同 Java 容器的类加载器中的问题...... 使用这种技术是有充分理由的。如果你需要 ('github/node_modules/mongoose'),你使用的是 github 使用的同一个 mongoose 实例,所以你共享它的连接池。这种技术对于确保您使用相同的版本也很有用。 无法保证依赖项会存在于嵌套的node_module 中。 IIUC,如果相同版本的依赖被另一个模块使用,它可能会被提升到根node_modules 我想说,如果您控制上游项目并且它正在处理 mongoose 逻辑,即一种特殊的 orm 案例,则应该让上游项目明确解决依赖关系,而您定制的 mongoose orm 模块的所有消费者应该使用在所述定制的猫鼬模块中定义的猫鼬版本。在这种情况下,由于您无法控制上游项目,因此您应该明确定义您的依赖项。【参考方案2】:

对于更健壮的情况,在测试等情况下效果很好,可以使用以下函数:

var Module = require('module');
var path = require('path');

function requireFrom(self, parent, name) 
  var pPath = Module._resolveFilename(parent, self);
  var m = new Module(pPath, module);
  m.filename = pPath;
  m.paths = Module._nodeModulePaths(path.dirname(pPath));
  return m.require(name);

可以如下使用

requireFrom(module, 'github_dependency', 'mongoose')

【讨论】:

self 参数应该是什么?我无法从上下文中判断。 ^ 忽略我的评论。我是一个nodejs n00b,没有意识到module本身就是一个保留关键字!!! 请注意,它不是保留关键字,它是通过包装器自动添加的内置每个模块变量。 nodejs.org/api/modules.html#modules_the_module_wrapper

以上是关于需要依赖节点模块中的另一个依赖项的主要内容,如果未能解决你的问题,请参考以下文章

npm 依赖项是不是需要其父包中的模块

yarn之安装依赖包

Odoo 14 CE 中的可选依赖项

如何避免节点需要加载相同的模块两次

如何使用依赖项创建AWS nodejs lambda函数

如何在 monorepo 中成功锁定节点模块依赖项?