为什么require()在从不同位置加载时会给我一个模块的新副本



我对Node.JS的开发很陌生,我正在尝试创建一个Hubot适配器。

hubot模块导出我需要使用的名为TextMessage的类。在我的适配器中,我创建了一个实例,并将其传递给正在运行的机器人,如下所示:

{Adapter, TextMessage} = require 'hubot'
class MyAdapter extends Adapter
onNewMessage: (text) =>
@receive new TextMessage text

然而,在Hubot自己的代码中,它检查我的消息是否是instanceof TextMessage。当我运行机器人并使用适配器时,此检查总是失败。

项目结构如下所示:

my-bot
|- node_modules
|- my-adapter
|  |- node_modules
|  |  |- hubot
|- hubot  

因此,my-adapter中的require('hubot')给了我一个与给my-bothubot模块不同的副本。

我很确定我没有理解节点模块的一些基本概念。我做错了什么?

这样设计的原因是,模块可以始终获得"新"版本(未被任何库(如您的库)修改)。一般来说,如果您require()其中一个依赖项,那么您应该能够依赖该模块的默认行为(替代方案不可预测且可能不安全。)

如果你的模块的目的是适应另一个模块,那么你应该:

返回修改后的模块

例如,您的模块可能会执行以下操作:

module.exports = require('hubot');
// ... your custom modifications

或者:

var hubot = module.exports.hubot = require('hubot');

这意味着应用程序本身不依赖于hubot,而只依赖于您的模块。

不将hubot列为适配器的依赖项

Node.js的require()调用级联到路径上,所以如果你只是不将hubot作为依赖项安装,那么你仍然可以require()它,它将使用应用程序中的版本。

这意味着可以在不安装hubot的情况下安装模块,从而导致问题,但另一方面,它也允许多个模块修改同一基本模块。

就我个人而言,我会选择第二种选择。

最新更新