如何在node.js插件中创建命名空间层次结构?

时间:2016-06-13 02:46:32

标签: node.js v8 node.js-addon node.js-nan

我正在创建一个node.js插件,它有很多类。我想在分层命名空间中组织它们。如果我在Javascript中这样做,它看起来像这样

var com = function() {};

com.example = function() {};

com.example.Person = function () {};

var p = new com.example.Person();

我使用Nan来编写我的node.js绑定。为了达到上述结果,我编写了如下代码:

com.h

namespace addon {
  void init(Local<Object> exports);
}

com.cpp

void addon::init(Local<Object> exports)
{
  addon::Example::Init(exports);
}

NODE_MODULE(com, com::init)

example.h文件

namespace addon {
  class Example : public Nan::ObjectWrap {
    static void Init(v8::Local<v8::Object> exports);
  }
}

example.cpp

void addon::Example::Init(v8::Local<v8::Object> exports) {

  // Prepare constructor template
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("example").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  addon::Person::Init(tpl);

  constructor.Reset(tpl->GetFunction());
}

person.h

namespace addon {
  class Person : public Nan::ObjectWrap {
    static void Init(v8::Local<v8::FunctionTemplate> exports);
  }
}

person.cpp

void addon::Person::Init(v8::Local<v8::FunctionTemplate> nmspace) {
  Nan::HandleScope scope;

  // Prepare constructor template
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("Person").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  // ...

  constructor.Reset(tpl->GetFunction());
  nmspace->Set(Nan::New("Person").ToLocalChecked(), tpl->GetFunction()); // XXXXXX

}

此代码在运行时编译并成功传递测试。但是,当加载插件时我收到警告。

(node) v8::FunctionTemplate::Set() with non-primitive values is deprecated
(node) and will stop working in the next major release.

打印堆栈跟踪。此跟踪的顶部位于标记为XXXXXX的行中。

如果这不是将FunctionTemplate定义为另一个FunctionTemplate成员的推荐方法,那么实现它的正确方法是什么?有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我发现了一种简单的方法。我发现我可以使用以下Javascript代码实现相同的功能。

var com = {};
com.example = {};
com.example.Person = function () {};
var p = new com.example.Person();

所以我发现为Example定义一个ObjectWrap类是完全没必要的。相反,我将其定义为一个简单的对象

v8::Isolate *isolate = v8::Isolate::GetCurrent();
v8::Handle<Object> example = v8::Object::New(isolate);

然后将其传递给Person::Init(),就像这样

void addon::Person::Init(v8::Local<v8::Object> nmspace) {
  // ...
  nmspace->Set(Nan::New("Person").ToLocalChecked(), tpl->GetFunction());
}

生成的代码无需任何警告或错误即可运行。