Home > Software engineering >  What semantics of `require()` make class definitions unavailable in Javascript?
What semantics of `require()` make class definitions unavailable in Javascript?

Time:10-21

I have a file allocation.js which defines class Allocation {...}. I have another file, test.js, which has require('./allocation.js') and on the next line a = new Allocation; which generates ReferenceError: Allocation is not defined. If I paste the contents of allocation.js into test.js where the require is and comment out the require, the code works fine. Is it possible to separate class definitions out into other files and if so, what am I doing wrong?

CodePudding user response:

You need to export the class from the file.

module.exports = Allocation;

Then you can import it in the other file.

var Allocation = require('./allocation.js');

CodePudding user response:

There are two aspects of require that I needed to know:

  1. require is NOT part of Javascript, but rather part of node.js, and it only has the ability to return an object.
  2. require allows the code to process another file, "treated as a module", which has its own scope. In order for the caller of require to use anything defined in that (other) scope, it must be set as a property of module.exports, which is the return value of the require function.

The scoping of the required file is the main reason that inserting its contents works but require does not, at least not the way I did it. @Fastnlight shows how to "import" the class definition into the calling file, and how to expose it from the file you require.

While finding this answer, I also ran into the the "exports" shortcut, which is that in a file, the keyword exports is the same object as module.exports, and so if you want to expose something, you can make it a property of exports (or of module.exports, which is the same thing). You can also make require return whatever you want with module.exports = (whatever you want), but this does not work with exports = (whatever you want) because you are overwriting the value instead of adding a property, and after exports = (whatever you want), exports will be thrown away and invisible to the caller.

I learned this from https://nodejs.org/docs/latest-v16.x/api/modules.html#modules-commonjs-modules

  • Related