0

This seems like a simple thing but I'm a bit of a node/javascript newbie. How can I import a class from another file using node 7.0.0?

I defined my class in one file:

'use strict';

class MyClass {
  ...
};

module.exports = MyClass;

And I want to use it in another class:

var MyClass = require('./path/to/otherfile');
...
var myclass = new MyClass(some param);

But I'm getting an error from my linter saying

TypeError: Class constructor MyClass cannot be invoked without 'new'
Louis
  • 146,715
  • 28
  • 274
  • 320
Barodapride
  • 3,475
  • 4
  • 25
  • 36
  • And does Node throw an error? If it's just the linter, does it matter? – adeneo Nov 09 '16 at 21:06
  • You are probably calling `MyClass()` without `new` keyword somewhere else in the code. – madox2 Nov 09 '16 at 21:07
  • 1
    If you do `module.exports.MyClass` does it still show that error – adeneo Nov 09 '16 at 21:09
  • why dont you use `export default MyClass` ? – The Reason Nov 09 '16 at 21:52
  • @Cruiser using `module.exports.MyClass = MyClass;` would break the code instead of fixing it. If you did it like you suggest then you'd either have to use `var MyClass = require('./path/to/otherfile').MyClass;` in the `require` line or `var myclass = new MyClass.MyClass();` in the constructor call which is not what the callling code looks like. See [my answer](http://stackoverflow.com/questions/40515954/how-can-i-export-a-class-in-node/40516570#40516570) below. – rsp Nov 09 '16 at 21:55
  • @TheReason probably because it would give `SyntaxError: Unexpected token export` in Node 7.0.0 – rsp Nov 09 '16 at 21:57
  • @rsp oh i thought that it's at client side – The Reason Nov 09 '16 at 22:07
  • @rsp - I think most of us understood that the OP's code works just fine, even the OP. The suggestions was just to try to make the linter stop showing errors. Of course the require would have to be changed if one adds properties to the export, that seems obvious. Posting an answer that says the code works fine, without knowing what linter is used, or why it throws, seems somewhat counterintuitive, and probably doesn't solve the issues the OP has either ? – adeneo Nov 09 '16 at 22:12
  • I am so sorry, the linter is actually working, I simply misread the output. It seems that the issue is with the cucumber.js library I'm using - it tries to do some initialization and is not liking my class for some reason (error above). This is a cucumber.js project and is started by invoking the cucumber.js file which does some initialization that I suppose I need to investigate more about. – Barodapride Nov 09 '16 at 22:20
  • @adeneo Don't get me wrong. OP asked: "How can I import a class from another file using node 7.0.0?" and I answered as best as I could. Additionally I created a project on GitHub to test the code on Travis and as soon as the OP answers my question about the linter used then I'll add it to the project. In fact since it's on GitHub then you or OP can give me a pull request with the linter added and we'll see how the tests go which will hopefully help other people with the same problem. I'm curious myself what the result will be. Update: OP answered that the code if fine :) Great. – rsp Nov 09 '16 at 23:03
  • @Barodapride If the linter is actually woking then there is nothing more that could be added to [my answer below](http://stackoverflow.com/questions/40515954/how-can-i-export-a-class-in-node/40516570#40516570). You can consider [accepting it](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235) in its current form since I won't be able to add a linter to my tests if you say that it turns out that it's fine after all. – rsp Nov 09 '16 at 23:06

1 Answers1

2

This code is correct and works in Node 7.0.0. See this example:

File class.js:

'use strict';
class MyClass {
}
module.exports = MyClass;

File code.js:

var MyClass = require('./class.js');
var myclass = new MyClass();
console.log('OK');

Run:

node code.js

and you'll see:

OK

What is broken is not your code but your linter but you don't specify what linter are you using so it's hard to say anything more.

I don't know why people suggested that you should use module.exports.MyClass = MyClass; instead of module.exports = MyClass; - it would not only not fix the issue but would actually break the code giving you an error of:

TypeError: MyClass is not a constructor 

Also to people suggesting that this should be used:

export default MyClass;

No, it would give an error in Node 7.0.0:

SyntaxError: Unexpected token export

After reading the comments to this question I wonder how many people have actually run the code because as it turns out the code works fine but all the "solutions" in the comments break it.

I made a GitHub project with the original code and suggested solutions tested on Travis with Node versions 4, 5, 6, and 7. You can see it here:

with test results available at:

When I know which linter is causing the problem I'll add it to the project and we'll see what can be done about it.

rsp
  • 107,747
  • 29
  • 201
  • 177
  • As stated in the comments the issue was not related to the linter but rather just to cucumber.js. I had to move the external class into another directory outside of the cucumber features/ to resolve the issue. This response does answer the question of how to export a class in node.js – Barodapride Nov 10 '16 at 01:39