Node-API 版本矩阵


¥Node-API version matrix

在版本 9 之前,Node-API 版本是附加的,并且版本独立于 Node.js。这意味着任何版本都是先前版本的扩展,因为它拥有先前版本的所有 API 并添加了一些内容。每个 Node.js 版本仅支持一个 Node-API 版本。例如,v18.15.0 仅支持 Node-API 版本 8。实现 ABI 稳定性是因为 8 是所有以前版本的严格超集。

¥Up until version 9, Node-API versions were additive and versioned independently from Node.js. This meant that any version was an extension to the previous version in that it had all of the APIs from the previous version with some additions. Each Node.js version only supported a single Node-API version. For example v18.15.0 supports only Node-API version 8. ABI stability was achieved because 8 was a strict superset of all previous versions.

从版本 9 开始,虽然 Node-API 版本继续独立进行版本控制,但与 Node-API 版本 9 一起运行的附加组件可能需要更新代码才能与 Node-API 版本 10 一起运行。然而,ABI 稳定性得以保持,因为支持高于 8 的 Node-API 版本的 Node.js 版本将支持 8 及其支持的最高版本之间的所有版本,并且将默认提供版本 8 API,除非附加组件选择加入 更高的 Node-API 版本。这种方法提供了更好地优化现有 Node-API 功能的灵活性,同时保持 ABI 稳定性。现有的附加组件可以继续运行,无需使用早期版本的 Node-API 重新编译。如果附加组件需要较新 Node-API 版本的功能,则无论如何都需要更改现有代码并重新编译才能使用这些新功能。

¥As of version 9, while Node-API versions continue to be versioned independently an add-on that ran with Node-API version 9 may need code updates to run with Node-API version 10. ABI stability is maintained, however, because Node.js versions that support Node-API versions higher than 8 will support all versions between 8 and the highest version they support and will default to providing the version 8 APIs unless an add-on opts into a higher Node-API version. This approach provides the flexibility of better optimizing existing Node-API functions while maintaining ABI stability. Existing add-ons can continue to run without recompilation using an earlier version of Node-API. If an add-on needs functionality from a newer Node-API version, changes to existing code and recompilation will be needed to use those new functions anyway.

在支持 Node-API 版本 9 及更高版本的 Node.js 版本中,定义 NAPI_VERSION=X 并使用现有的附加组件初始化宏会将请求的 Node-API 版本烘焙到附加组件中,该版本将在运行时使用。如果未设置 NAPI_VERSION,则默认为 8。

¥In versions of Node.js that support Node-API version 9 and later, defining NAPI_VERSION=X and using the existing add-on initialization macros will bake in the requested Node-API version that will be used at runtime into the add-on. If NAPI_VERSION is not set it will default to 8.

此表在较旧的流中可能不是最新的,最新的信息位于最新的 API 文档中:Node-API 版本矩阵

¥This table may not be up to date in older streams, the most up to date information is in the latest API documentation in: Node-API version matrix

Node-API 版本 支持于
10 v22.14.0+、23.6.0+ 及所有后续版本
9 v18.17.0+、20.3.0+、21.0.0 及所有更高版本
8 v12.22.0+、v14.17.0+、v15.12.0+、16.0.0 及所有更高版本
7 v10.23.0+、v12.19.0+、v14.12.0+、15.0.0 及所有更高版本
6 v10.20.0+、v12.17.0+、14.0.0 及所有更高版本
5 v10.17.0+、v12.11.0+、13.0.0 及所有更高版本
4 v10.16.0+、v11.8.0+、12.0.0 及所有更高版本
3 v6.14.2*、8.11.2+、v9.11.0+*、10.0.0 及所有更高版本
2 v8.10.0+、v9.3.0+、10.0.0 及所有更高版本
1 v8.6.0+**、v9.0.0+*、10.0.0 及所有更高版本
  • Node-API 是实验性的。

¥* Node-API was experimental.

** Node.js 8.0.0 包含 Node-API 作为实验性的。它作为 Node-API 版本 1 发布,但继续改进直到 Node.js 8.6.0。API 在 Node.js 8.6.0 之前的版本中有所不同。我们推荐 Node-API 版本 3 或更高版本。

¥** Node.js 8.0.0 included Node-API as experimental. It was released as Node-API version 1 but continued to evolve until Node.js 8.6.0. The API is different in versions prior to Node.js 8.6.0. We recommend Node-API version 3 or later.

为 Node-API 记录的每个 API 都有一个名为 added in: 的标头,而稳定的 API 将有一个额外的标头 Node-API version:。当使用支持 Node-API version: 或更高版本中所示的 Node-API 版本的 Node.js 版本时,API 可直接使用。当使用不支持列出的 Node-API version: 的 Node.js 版本时,或者如果没有列出 Node-API version:,则只有在包含 node_api.hjs_native_api.h 之前包含 #define NAPI_EXPERIMENTAL 时,API 才可用。如果某个 API 在晚于 added in: 中所示版本的 Node.js 版本上似乎不可用,那么这很可能是明显缺失的原因。

¥Each API documented for Node-API will have a header named added in:, and APIs which are stable will have the additional header Node-API version:. APIs are directly usable when using a Node.js version which supports the Node-API version shown in Node-API version: or higher. When using a Node.js version that does not support the Node-API version: listed or if there is no Node-API version: listed, then the API will only be available if #define NAPI_EXPERIMENTAL precedes the inclusion of node_api.h or js_native_api.h. If an API appears not to be available on a version of Node.js which is later than the one shown in added in: then this is most likely the reason for the apparent absence.

与从原生代码访问 ECMAScript 功能严格相关的 Node-API 可以在 js_native_api.hjs_native_api_types.h 中单独找到。这些标头中定义的 API 包含在 node_api.hnode_api_types.h 中。标头以这种方式构造,以便允许在 Node.js 之外实现 Node-API。对于这些实现,Node.js 特定的 API 可能不适用。

¥The Node-APIs associated strictly with accessing ECMAScript features from native code can be found separately in js_native_api.h and js_native_api_types.h. The APIs defined in these headers are included in node_api.h and node_api_types.h. The headers are structured in this way in order to allow implementations of Node-API outside of Node.js. For those implementations the Node.js specific APIs may not be applicable.

插件的 Node.js 特定部分可以与将实际功能暴露给 JavaScript 环境的代码分开,以便后者可以与 Node-API 的多个实现一起使用。在下面的示例中,addon.caddon.h 仅引用 js_native_api.h。这确保了 addon.c 可以被重用以针对 Node-API 的 Node.js 实现或 Node.js 之外的任何 Node-API 实现进行编译。

¥The Node.js-specific parts of an addon can be separated from the code that exposes the actual functionality to the JavaScript environment so that the latter may be used with multiple implementations of Node-API. In the example below, addon.c and addon.h refer only to js_native_api.h. This ensures that addon.c can be reused to compile against either the Node.js implementation of Node-API or any implementation of Node-API outside of Node.js.

addon_node.c 是一个单独的文件,其中包含插件的 Node.js 特定入口点,并在插件加载到 Node.js 环境时通过调用 addon.c 来实例化插件。

¥addon_node.c is a separate file that contains the Node.js specific entry point to the addon and which instantiates the addon by calling into addon.c when the addon is loaded into a Node.js environment.

// addon.h
#ifndef _ADDON_H_
#define _ADDON_H_
#include <js_native_api.h>
napi_value create_addon(napi_env env);
#endif  // _ADDON_H_ 
// addon.c
#include "addon.h"

#define NODE_API_CALL(env, call)                                  \
  do {                                                            \
    napi_status status = (call);                                  \
    if (status != napi_ok) {                                      \
      const napi_extended_error_info* error_info = NULL;          \
      napi_get_last_error_info((env), &error_info);               \
      const char* err_message = error_info->error_message;        \
      bool is_pending;                                            \
      napi_is_exception_pending((env), &is_pending);              \
      /* If an exception is already pending, don't rethrow it */  \
      if (!is_pending) {                                          \
        const char* message = (err_message == NULL)               \
            ? "empty error message"                               \
            : err_message;                                        \
        napi_throw_error((env), NULL, message);                   \
      }                                                           \
      return NULL;                                                \
    }                                                             \
  } while(0)

static napi_value
DoSomethingUseful(napi_env env, napi_callback_info info) {
  // Do something useful.
  return NULL;
}

napi_value create_addon(napi_env env) {
  napi_value result;
  NODE_API_CALL(env, napi_create_object(env, &result));

  napi_value exported_function;
  NODE_API_CALL(env, napi_create_function(env,
                                          "doSomethingUseful",
                                          NAPI_AUTO_LENGTH,
                                          DoSomethingUseful,
                                          NULL,
                                          &exported_function));

  NODE_API_CALL(env, napi_set_named_property(env,
                                             result,
                                             "doSomethingUseful",
                                             exported_function));

  return result;
} 
// addon_node.c
#include <node_api.h>
#include "addon.h"

NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
  // This function body is expected to return a `napi_value`.
  // The variables `napi_env env` and `napi_value exports` may be used within
  // the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.
  return create_addon(env);
}