Run NAN tests
mainTo run the NAN test suite, use one of the following methods:
Using npm:
npm install
npm run-script rebuild-tests
npm testUsing make:
npm install
make testrepository·main·Indexed 25 days ago
https://github.com/nodejs/nanA C++ header library providing macros and utilities to simplify the development of native Node.js addons. NAN ensures compatibility across Node.js versions (0.8 to 26) by abstracting V8 and Node core changes. It provides cross-version compatible implementations for HandleScopes, Persistent references, JavaScript value creation via Nan::New(), type conversion with Nan::To(), and asynchronous execution through AsyncWorker, AsyncProgressWorker, and AsyncQueueWorker.
To run the NAN test suite, use one of the following methods:
Using npm:
npm install
npm run-script rebuild-tests
npm testUsing make:
npm install
make testThe 1to2 tool naively converts source code files from NAN 1 to NAN 2.
Warning: This tool performs in-place rewrites of input files. It may produce erroneous conversions, false positives, or missed opportunities. Always ensure you have backups of your source code before running this tool, and manually review all changes to perform necessary touchups.
To run the async_pi_estimate example, you must first compile the native addon using node-gyp and then execute the JavaScript entry point.
node-gyp rebuild
node ./addon.jsFor practical implementations of NAN, you can refer to several resources:
To use NAN in your native Node.js addon, add it as a dependency using your preferred package manager.
$ npm install nanWhen using Nan::ObjectWrap::Unwrap<T>(handle), ensure the handle is a valid JavaScript object wrapped by your class.
info.Holder() if the method was installed via Nan::SetPrototypeMethod(). In Node.js 0.12+, info.This() is also safe as the invocation will be rejected if the type doesn't match.info.Holder(). Instead, define accessors on the instance template or use info.This() after verifying it is a valid object.Warning: In Node.js 0.10 and earlier, calling Unwrap on info.This() when the method is on the prototype chain (but not the instance itself) can cause crashes or memory corruption.
#include <nan.h> in your C++ files, you must add the NAN include path to your binding.gyp file. You can dynamically resolve the path using a node command within the include_dirs section.The Nan::MakeCallback() functions are deprecated in Node.js 10+ because they do not provide a mechanism to preserve async context.
Recommendation: Use the AsyncResource class and AsyncResource::runInAsyncScope instead of Nan::MakeCallback or v8::Function#Call() to ensure compatibility with async_hooks, domains, and async debugging.
NAN_DEPRECATED
v8::Local<v8::Value> Nan::MakeCallback(v8::Local<v8::Object> target,
v8::Local<v8::Function> func,
int argc,
v8::Local<v8::Value>* argv);
NAN_DEPRECATED
v8::Local<v8::Value> Nan::MakeCallback(v8::Local<v8::Object> target,
v8::Local<v8::String> symbol,
int argc,
v8::Local<v8::Value>* argv);
NAN_DEPRECATED
v8::Local<v8::Value> Nan::MakeCallback(v8::Local<v8::Object> target,
const char* method,
int argc,
v8::Local<v8::Value>* argv);If you are attempting to compile against Node.js 0.12 on OSX using modern compilers, you may encounter a V8 header error where CreateHandle is a protected member of v8::HandleScope.
Error Example:
CXX(target) Release/obj.target/accessors/cpp/accessors.o
In file included from ../cpp/accessors.cpp:9:
In file included from ../../nan.h:51:
In file included from /Users/ofrobots/.node-gyp/0.12.18/include/node/node.h:61:
/Users/ofrobots/.node-gyp/0.12.18/include/node/v8.h:5800:54: error: 'CreateHandle' is a protected member of 'v8::HandleScope'
return Handle<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
~~~~~~~~~~~~~^~~~~~~~~~~~~~Workarounds:
v8::Handle a friend of v8::HandleScope.Nan::IdleNotification(int idle_time_in_ms) method is deprecated and was removed in V8 12.7.41. Developers should avoid using this method in new code.You can implement a factory pattern where a JavaScript function returns new instances of a wrapped C++ class. This is done by creating a Nan::ObjectWrap class and providing a static method (e.g., NewInstance) that uses Nan::NewInstance to return a new object.
Nan::ObjectWrap.InstanceTemplate()->SetInternalFieldCount(1).New method to handle IsConstructCall() (for new MyObject()) and non-construct calls (for factory usage).obj->Wrap(info.This()) inside the constructor logic.class MyFactoryObject : public Nan::ObjectWrap {
public:
static NAN_MODULE_INIT(Init) {
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "getValue", GetValue);
constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked());
}
static NAN_METHOD(NewInstance) {
v8::Local<v8::Function> cons = Nan::New(constructor());
double value = info[0]->IsNumber() ? Nan::To<double>(info[0]).FromJust() : 0;
const int argc = 1;
v8::Local<v8::Value> argv[1] = {Nan::New(value)};
info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
}
inline double value() const { return value_; }
private:
explicit MyFactoryObject(double value = 0) : value_(value) {}
~MyFactoryObject() {}
static NAN_METHOD(New) {
if (info.IsConstructCall()) {
double value = info[0]->IsNumber() ? Nan::To<double>(info[0]).FromJust() : 0;
MyFactoryObject * obj = new MyFactoryObject(value);
obj->Wrap(info.This());
info.GetReturnValue().Set(info.This());
} else {
const int argc = 1;
v8::Local<v8::Value> argv[argc] = {info[0]};
v8::Local<v8::Function> cons = Nan::New(constructor());
info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
}
}
static NAN_METHOD(GetValue) {
MyFactoryObject* obj = ObjectWrap::Unwrap<MyFactoryObject>(info.Holder());
info.GetReturnValue().Set(obj->value_);
}
static inline Nan::Persistent<v8::Function> & constructor() {
static Nan::Persistent<v8::Function> my_constructor;
return my_constructor;
}
double value_;
};
NAN_MODULE_INIT(Init) {
MyFactoryObject::Init(target);
Nan::Set(target,
Nan::New<v8::String>("newFactoryObjectInstance").ToLocalChecked(),
Nan::GetFunction(
Nan::New<v8::FunctionTemplate>(MyFactoryObject::NewInstance)).ToLocalChecked()
);
}
NODE_MODULE(wrappedobjectfactory, Init)A method must follow the Nan::FunctionCallback signature. A HandleScope is implicitly created for you, so you do not need to declare a new one within the method.
Signature:
typedef void(*FunctionCallback)(const FunctionCallbackInfo<v8::Value>&);You can use the NAN_METHOD(methodname) macro for compatibility with NAN v1 declarations.
void MethodName(const Nan::FunctionCallbackInfo<v8::Value>& info) {
...
}