oppnom
oppnom

Reputation: 43

Require and instanceof

Can someone please explain my why this happens and how to make it work correctly:

Imagine we have a module published on NPM called test-module with the following content:

function Class() {

}

module.exports = Class;

Then let's imagine our project folder looks like this:

[root]
-- child

and let's assume both the root and child folders have their own npm packages installed including our test-module module (same version of the module used in both folders).

Then we have the following files in the project:

// [root]/index.js

var Test = require("test-module");
var childTest = require("./child");

var one = new Test();

childTest(one);

and

// [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);
}

If we were to run node index.js on the root folder the result in the console is this:

#1: false
#2: true

Question(s)

Shouldn't both #1 and #2 statements equal to true? Why the statement marked as #1 in the console log equals to false even though test argument (one) is actually the instance of our test-module module, it just isn't installed in the same folder? Is there a way to make it work like this without some hackish solutions that came up to my mind?

Upvotes: 4

Views: 798

Answers (1)

Farid Nouri Neshat
Farid Nouri Neshat

Reputation: 30430

Well the problem is that you have two copies of the class in different files. Just because they are the same version doesn't mean Javascript will treat them the same. Node.js in particular doesn't really care about the version of the module and if there are other copies about it.

Even though they have the same name, for Javascript they are different classes. Because every time the class code executes, it'll be a unique function. You can observe it like this:

const ClassA = function SomeClass() {};
const ClassB = function SomeClass() {};
new ClassA() instanceof SomeClass // > false

Now you probably wonder what you have to do, to share the same exact module in your case. Normally what people do is to have only one copy of the module is installed on the root level and then specify the module version in the child with peerDependencies which npm ensures it matches. Here's a good blog post about this issue.

Upvotes: 3

Related Questions