模块注册


🌐 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.