10

I'm creating a crawler to parse a game I have this function on the main file (crawler.js)

function kicked() {
    try {
        info.logged = false;
        info.next_login = 0;
        info.login_tries = 0;
        report('Crawler disconnected from game, reconnecting.');
    }
    catch (error) {
        report('Disconected() error => ' + error);
    }
}

And i have

module.exports = { kicked: kicked };

and in another file (renew session) i have

var crawler = require('../../crawler');

but when i call the crawler.kicked() i get undefined and if i use console.log(crawler); it shows an empty object no errors nothing, just an empty object and i can't find why the file isn't exporting the function any help ?

Andreas
  • 21,535
  • 7
  • 47
  • 56
user2942910
  • 173
  • 1
  • 3
  • 9
  • 1
    Add `.js` to the end of the word `crawler` in your `require`. You need to specify the file, as opposed to a name. – JosephGarrone Feb 21 '16 at 10:16
  • 2
    Possible duplicate of [node.js: require returns an empty object](http://stackoverflow.com/questions/23875233/node-js-require-returns-an-empty-object) – Ziki Feb 21 '16 at 10:21

5 Answers5

30

The problem is that you have cyclic dependencies, which is what happens when A requires B, which requires A, etc. These are not always a problem. Node can handle cyclic dependencies. However, without a very good understanding of how Node modules are resolved, you are likely to run into problems (usually the empty-object problem).

Let's take a closer look at what's going on here:

  1. You start your main script (crawler.js), which begins to execute.
  2. crawler.js requires session.js.
  3. Now session.js starts to execute its top-level code. Remember that crawler.js has not finished executing its own top-level code.
  4. Now session.js requires crawler.js. But crawler.js has nothing to export (yet). It hasn't yet reached the bottom of the file (it's still up at the top executing its require calls).

So now we can see what's going on. The empty object is the default exports object. When you do module.exports = {...}, you reassign the module's exports property to a new object. But module.exports has not yet been reassigned, for the reasons mentioned above.

The solution will be to rethink your code. I suggest trying to eliminate circular dependencies altogether; once you have a better grasp of how they work, you may want to use them from time to time. Your main file should probably not have any exports. Try putting your kicked function in another file, and require that where needed.

McMath
  • 6,862
  • 2
  • 28
  • 33
1

Add .js to the end of the word crawler in your require. You need to specify the file, as opposed to a name.

There is a good article here. A little outdated, but I think it's still pretty accurate.

Here's a snippet:

First, Node.js looks to see if the given module is a core module - Node.js comes with many modules compiled directly into the executable binary (ex. http, fs, sys, events, path, etc.). These core modules will always take precedence in the loading algorithm.

If the given module is not a core module, Node.js will then begin to search for a directory named, "node_modules". It will start in the current directory (relative to the currently-executing Javascript file in Node) and then work its way up the folder hierarchy, checking each level for a node_modules folder.

...

If it still can't find the file in this directory-spidering manner, Node.js will then proceed to look at the directory paths outlined in the "require.paths" array. The paths values in this array default to the paths defined, in part, by the environmental variable, NODE_PATH; but, they can be updated programmatically within a Node.js application.

Community
  • 1
  • 1
JosephGarrone
  • 4,081
  • 3
  • 38
  • 61
  • tried and the result is node crawler.js -> {} {} {} – user2942910 Feb 21 '16 at 10:18
  • @user2942910 can you post the code where you try to use it? – JosephGarrone Feb 21 '16 at 10:19
  • Main file http://pastebin.com/rL5UiR4k, file that call the function from the main file http://pastebin.com/8Fbusw2D – user2942910 Feb 21 '16 at 10:23
  • @user2942910 can you also post a directory tree of your project? `tree` on windows. – JosephGarrone Feb 21 '16 at 10:24
  • @user2942910 You seem to be importing `crawler` as `kicked` and then using `crawler.kicked()`. What if you try `kicked.kicked()`? – JosephGarrone Feb 21 '16 at 10:27
  • TypeError: kicked.kicked is not a function at profile (C:\Users\Luis\Desktop\OmertaNode\Ingame_Bot\modules\game\profile.js:18:28) – user2942910 Feb 21 '16 at 10:30
  • What are the name's of those files you posted, I can't work out which one is which in the tree. – JosephGarrone Feb 21 '16 at 10:31
  • I think the issue may be circular dependencies. But to know for sure, we need one crucial piece of information: from which file are you trying to require `crawler`? – McMath Feb 21 '16 at 10:32
  • 1
    I think crawler is the main file, which is what is causing the issues. Because it includes the sub file, which then tries to include itself again. You are better off passing the `crawler` object in. – JosephGarrone Feb 21 '16 at 10:32
  • Yes, I see that crawler is the main file. But which file is requiring crawler? I suspect it will turn out to be circular. – McMath Feb 21 '16 at 10:33
  • @McMath yeh, I agree with you. I think first file linked is login.js and second file is crawler.js – JosephGarrone Feb 21 '16 at 10:35
  • The other file is the session.js – user2942910 Feb 21 '16 at 10:35
  • @McMath Main file crawler.js, the other is session.js – user2942910 Feb 21 '16 at 10:36
  • Yeh, bit hard to see exactly what is wrong unless you can upload the entire project. I think most likely you've got a circular reference error. I recommend you restructure your project to include downwards (IE: Program starts from a file in the root directory, and includes in a downward direction - not upward as session.js seems to do) – JosephGarrone Feb 21 '16 at 10:37
  • So I was right. It is a circular dependencies issue. I'll see if I can elaborate in an answer – McMath Feb 21 '16 at 10:37
1

you can also directly assign the function as a property of module.exports, as the following:

module.exports.kicked = () => ...

Though this will work, you need to specify module.exports.kicked() every time you want to call the function, which, for internal file use, can get annoying. But not a bad quick-fix solution

Julian
  • 550
  • 1
  • 4
  • 16
0

my code works when I remove the '/'.. Here is what I wrote and it works fine. require('.emily'); So you can write var crawler = require('.crawler'); and let me know how us know if you have solved this.

0

Its happening because of circular dependency resolution. A -> B -> A To fix this, don't use require at the top of the file, use it inside the required function.

function test(){
  const x = require('../file');
  ...
 }
ritesh
  • 177
  • 2
  • 4