我正在开发一个节点模块my-module
,后者依赖于另一个模块other-module
。因此,other-module
是我的模块的package.json中明确列出的依赖项。
由于我的模块只是other-module
d修改了require
的行为,因此other-module
只加载一次并且这个唯一的'实例'非常重要是在任何需要my
和other
的应用程序中引用的那个。
我希望根据节点的模块缓存策略保持这一点,但我在编写一个简单的测试应用程序时遇到的是:
如果my-module
在 npm install
之前other-module
为,那么后者将作为前者的依赖项引入。之后npm install
other-module
将它再次带入node_modules层次结构。然后,当我的模块需要other-module
时,节点会加载我的模块的“本地”副本,当应用程序require
时,第二次节点再次加载 ,(这次是由于第二个npm install
而安装的版本。这显然不是预期的结果。
如果my-module
在<{em> npm installe
之后为other-module
d ,那么我最终只能使用 other-module
的一个副本在node_modules中,我的测试应用程序按预期工作。
这种行为让我再次查看节点的相关政策,果然我遇到了“模块缓存警告”:
模块根据其解析的文件名进行缓存。由于模块可能会根据调用模块的位置(从node_modules文件夹加载)解析为不同的文件名,因此不能保证require('foo')将始终返回完全相同的对象,如果它将解析为不同的文件
此时看起来我的模块可能会或可能不会按预期运行,具体取决于npm install
的顺序。
我缺少哪些最佳做法?有没有办法在不改变模块工作方式的情况下避免这种混乱?
答案 0 :(得分:3)
简短回答:你不能。
正如您所指出的,node将从最本地的位置加载所需的模块。据我所知,这是包管理器的独特之处,它使您无需关心模块的确切依赖关系树。 Node和npm会为你解决这个问题。在我看来,这是非常好的。
通过让您的模块有机会需要他们所需的精确版本,可以避免依赖性地狱。
我认为你要做的事情,除非我不完全理解你的问题,不是好的节点练习。加载模块并将其分配给局部变量。应避免使用全局状态,因为这会导致相当笨拙和不可测试的代码。此外,如果您成功将
但请记住,这篇文章只是一个人的意见。如果您在此处找不到更多答案,请在节点的IRC频道之外的其他地方发布您的问题。
答案 1 :(得分:0)
我在用jest开发测试时遇到了类似的问题。
以下语句允许您在不同的上下文中再次加载相同的模块:
jest.resetModules();