模块注册


¥Module registration

Node-API 模块的注册方式与其他模块类似,只是不使用 NODE_MODULE 宏,而是使用以下内容:

¥Node-API modules are registered in a manner similar to other modules except that instead of using the NODE_MODULE macro the following is used:

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) 

下一个区别是 Init 方法的签名。对于 Node-API 模块,它如下所示:

¥The next difference is the signature for the Init method. For a Node-API module it is as follows:

napi_value Init(napi_env env, napi_value exports); 

Init 的返回值被视为模块的 exports 对象。为方便起见,Init 方法通过 exports 参数传递一个空对象。如果 Init 返回 NULL,则作为 exports 传递的参数由模块导出。Node-API 模块无法修改 module 对象,但可以将任何内容指定为模块的 exports 属性。

¥The return value from Init is treated as the exports object for the module. The Init method is passed an empty object via the exports parameter as a convenience. If Init returns NULL, the parameter passed as exports is exported by the module. Node-API modules cannot modify the module object but can specify anything as the exports property of the module.

将方法 hello 添加为函数,以便它可以作为插件提供的方法调用:

¥To add the method hello as a function so that it can be called as a method provided by the addon:

napi_value Init(napi_env env, napi_value exports) {
  napi_status status;
  napi_property_descriptor desc = {
    "hello",
    NULL,
    Method,
    NULL,
    NULL,
    NULL,
    napi_writable | napi_enumerable | napi_configurable,
    NULL
  };
  status = napi_define_properties(env, exports, 1, &desc);
  if (status != napi_ok) return NULL;
  return exports;
} 

要为插件设置 require() 返回的函数:

¥To set a function to be returned by the require() for the addon:

napi_value Init(napi_env env, napi_value exports) {
  napi_value method;
  napi_status status;
  status = napi_create_function(env, "exports", NAPI_AUTO_LENGTH, Method, NULL, &method);
  if (status != napi_ok) return NULL;
  return method;
} 

定义一个类以便创建新实例(通常与 对象封装 一起使用):

¥To define a class so that new instances can be created (often used with Object wrap):

// NOTE: partial example, not all referenced code is included
napi_value Init(napi_env env, napi_value exports) {
  napi_status status;
  napi_property_descriptor properties[] = {
    { "value", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },
    DECLARE_NAPI_METHOD("plusOne", PlusOne),
    DECLARE_NAPI_METHOD("multiply", Multiply),
  };

  napi_value cons;
  status =
      napi_define_class(env, "MyObject", New, NULL, 3, properties, &cons);
  if (status != napi_ok) return NULL;

  status = napi_create_reference(env, cons, 1, &constructor);
  if (status != napi_ok) return NULL;

  status = napi_set_named_property(env, exports, "MyObject", cons);
  if (status != napi_ok) return NULL;

  return exports;
} 

你还可以使用 NAPI_MODULE_INIT 宏,它充当 NAPI_MODULE 的简写并定义 Init 函数:

¥You can also use the NAPI_MODULE_INIT macro, which acts as a shorthand for NAPI_MODULE and defining an Init function:

NAPI_MODULE_INIT() {
  napi_value answer;
  napi_status result;

  status = napi_create_int64(env, 42, &answer);
  if (status != napi_ok) return NULL;

  status = napi_set_named_property(env, exports, "answer", answer);
  if (status != napi_ok) return NULL;

  return exports;
} 

所有 Node-API 插件都是上下文感知的,这意味着它们可以被加载多次。声明此类模块时有一些设计注意事项。上下文感知的插件 上的文档提供了更多详细信息。

¥All Node-API addons are context-aware, meaning they may be loaded multiple times. There are a few design considerations when declaring such a module. The documentation on context-aware addons provides more details.

宏调用后,变量 envexports 将在函数体内可用。

¥The variables env and exports will be available inside the function body following the macro invocation.

有关设置对象属性的更多详细信息,请参阅 使用 JavaScript 属性 部分。

¥For more details on setting properties on objects, see the section on Working with JavaScript properties.

有关一般构建插件模块的更多详细信息,请参阅现有 API。

¥For more details on building addon modules in general, refer to the existing API.