有人可以解释一下为什么会发生这种情况以及如何使其正常工作:
想象一下,我们在NPM上发布了一个名为notify_all()
的模块,内容如下:
test-module
然后我们假设我们的项目文件夹如下所示:
function Class() {
}
module.exports = Class;
让我们假设root和[root]
-- child
文件夹都安装了自己的child
软件包,包括我们的npm
模块(两个文件夹中使用的模块版本相同)。
然后我们在项目中有以下文件:
test-module
和
// [root]/index.js
var Test = require("test-module");
var childTest = require("./child");
var one = new Test();
childTest(one);
如果我们在根文件夹上运行// [root]/child/index.js
var Test = require("test-module");
var two = new Test();
module.exports = function(test) {
console.log("#1:", test instanceof Test);
console.log("#2:", two instanceof Test);
}
,则控制台中的结果为:
node index.js
#1: false
#2: true
和#1
语句不应该等于#2
吗?为什么控制台日志中标记为true
的语句等于#1
,即使false
参数(test
)实际上是我们one
模块的实例,它只是没有安装在同一个文件夹中?如果没有出现在我脑海中的一些黑客解决方案,有没有办法让它像这样工作?
答案 0 :(得分:1)
问题是你在不同的文件中有两个类的副本。仅仅因为它们是相同版本并不意味着Javascript会对它们进行同样的处理。特别是Node.js并不真正关心模块的版本以及是否有其他副本。
即使它们具有相同的名称,对于Javascript它们也是不同的类。因为每次类代码执行时,它都将是一个独特的函数。你可以这样观察它:
const ClassA = function SomeClass() {};
const ClassB = function SomeClass() {};
new ClassA() instanceof SomeClass // > false
现在您可能想知道您需要做什么,在您的案例中共享相同的模块。通常人们所做的是在根级别只安装一个模块副本,然后在peerDependencies
子项中指定模块版本,npm确保它匹配。 Here's a good blog post about this issue