Как да създадете йерархия на пространството от имена в добавката node.js?

Създавам добавка node.js, която има куп класове. Искам да ги организирам в йерархично пространство от имена. Ако правех това в Javascript, щеше да изглежда така

var com = function() {};

com.example = function() {};

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

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

Използвам Nan, за да напиша моето свързване на node.js. За да постигна горния резултат, написах код, както следва:

ком.ч

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

com.cpp

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

NODE_MODULE(com, com::init)

пример.з

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());
}

лице.ч

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, тогава какъв е правилният начин да го постигнете? Някакви идеи?


person Jayesh    schedule 13.06.2016    source източник


Отговори (1)


Намерих лесен начин да направя това. Хрумна ми, че мога да постигна същото със следния Javascript код.

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

Така че открих, че е напълно ненужно да дефинирам клас 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());
}

Полученият код работи без никакви предупреждения или грешки.

person Jayesh    schedule 13.06.2016