Search code examples
c++node.jsnode.js-addonnode.js-nan

Why is my NAN_METHOD not recognized?


I get the following error when trying to run my Node native extension (it builds without error). I'd like to know why I'm getting this error, since I'm doing everything correctly as far as I can tell.

./NodeTest/nodeTest.js:7
tester.Startup();
       ^

TypeError: tester.Startup is not a function
    at Object.<anonymous> (./NodeTest/nodeTest.js:7:8)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:383:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:496:3

Here is the 'nodeTest.cpp' file:

#include <nan.h>

NAN_METHOD(Startup)
{
    auto message = Nan::New("Native Startup() method called.").ToLocalChecked();

    info.GetReturnValue().Set(message);
}

NAN_MODULE_INIT(Initialize)
{
    NAN_EXPORT(target, Startup);
}

NODE_MODULE(nodeTest, Initialize);

Here is the 'nodeTest.js' file:

var tester = require('./nodeTest');
tester.Startup();

Here is the 'package.json' file:

{
  "name": "nodeTest",
  "version": "0.0.1",
  "scripts": {
    "install": "node-gyp rebuild",
    "compile": "node-gyp rebuild",
    "test": "node nodeTest.js"
  },
  "dependencies": {
    "nan": "^2.8.0"
  },
  "gypfile": true,
  "author": "BT",
  "license": "ISC",
  "main": "nodeTest.js",
  "keywords": [],
  "description": "NodeTest"
}

Here's the 'bindings.gyp' file:

{
  'targets': [{
    'target_name': "nodeTest",

    'include_dirs': [
      "<!(node -e \"require('nan')\")",
      "./src"
    ],

    'cflags': [
      "-Wall", "-std=c++11", "-fPIC"
    ],

    'sources': [
      "./src/nodeTest.cpp"
    ]
  },  # nodeTest target

  {
      "target_name": "copy_binary",
      "type": "none",
      "dependencies" : [ "nodeTest" ],
      "copies": [{
        'destination': '<(module_root_dir)',
        'files': ['<(module_root_dir)/build/Release/nodeTest.node']
      }]
  }  # copy target

  ] # 'targets'
}

Solution

  • The issue lies in the naming of your files. The entry point of your program is nodeTest.js which contains:

    var tester = require('./nodeTest');
    tester.Startup();
    

    Then you have nodeTest.cpp which will be compiled into nodeTest.node. But by using require('./nodeTest') instead of requiring nodeTest.node which is what you were trying to do, you were requiring nodeTest.js since .js is the default extension require will try. If it can’t find a .js file, it will try a .json file. After that, it will try to find a binary .node file.

    So nodeTest.js was requiring itself. In order to fix your problem, either change nodeTest.js to index.js or use the correct extension when using require.

    var tester = require('./nodeTest.node');
    tester.Startup();