如何避免节点需要加载相同的模块两次
我正在开发一个节点模块my-module
,而这又取决于另一个模块other-module
。 other-module
是一个在我的模块的package.json中明确列出的依赖项。
因为我other-module
只是通过require
d来修改other-module
模块的行为,所以重要的是other-module
other-module
只require
加载一次,并且这个一次性的“实例”是在任何需要my
应用程序中引用的实例和other
。
我期望这根据节点的模块caching策略保持真实,但是我在写一个简单的testing应用程序时遇到了这样的情况:
如果my-module
是npm install
在 other-module
之前,那么后者是作为前者的依赖而引入的。 npm install
other-module
再次将其带入node_modules层次结构中。 然后,当我的模块需要other-module
,节点加载我的模块的“本地”副本,当应用程序require
时,节点再次加载它(这次是由于第二次npm install
而安装的版本)。 这显然不是预期的结果。
如果my-module
是npm installe
在 other-module
那么我最终只有一个在node_modules other-module
的副本,我的testing应用程序按预期工作。
这种行为让我再次查看节点的相关策略,果然我遇到了“模块caching警告”:
模块基于他们parsing的文件名被caching。 由于模块可能会根据调用模块的位置(从node_modules文件夹加载)parsing为不同的文件名,因此不能保证require('foo')将始终返回完全相同的对象,如果parsing为不同的文件。
在这一点上,它看起来像我的模块可能会或可能不会像预期的取决于npm install
的顺序。
我有什么最佳做法吗? 有没有办法避免这个混乱,而不改变我的模块的工作方式?
简短的回答:你不能。
正如你所指出的那样,节点将从最本地的地方加载所需的模块。 就我所知,这是一个独立于包pipe理器的东西,它使您不必关心模块的确切依赖关系树。 节点和NPM将为您解决这个问题。 在我看来,这是非常好的。
通过给你的模块提供一个需要的确切版本的机会,简单地避免依赖地狱。
我认为你所要做的,除非我完全不了解你的问题,不是好的节点实践。 模块被加载并分配给一个局部variables。 应避免全局状态,因为这可能会导致相当尴尬和不可测的代码。 另外,如果你能成功地将修改过的模块注入到其他的人员代码中,那么不能保证他们的代码仍然可以工作。 这就像在老式的Prototype.js中一样,可以利用JavaScript内置的全局variables如String或者Array来破解代码。
但请记住,这个写作只是一个人的意见。 如果您在这里找不到更多答案,请在其他地方发布您的问题,如节点的IRC频道。
用开玩笑来开发testing时,我遇到了类似的问题。
以下语句将允许您在不同的上下文中再次加载相同的模块:
jest.resetModules();