前言C++作为nodejs的底层开发语言,具有高性能、复用性好的优点。用C++编写的chromev8引擎,加上libuv、http-parser、zlib等,现在是大前端技术的基础——nodejs。Nodejs还提供了一种编写C++扩展以提高性能的方法。然而,原生C++模块的开发一直是一个被忽视的角落。一部分原因是部分Node程序员是前端出身,C++的学习成本非常高。他们可能没有系统的C++知识。另一部分原因是node.js的C++扩展机制。它很复杂,需要了解v8的各种概念,包括隔离实例、虚拟机、上下文、句柄、内存回收(gc)、模板等。更可悲的是,随着版本的变化,一个编译出来的插件,在发布不久后,就会因为版本不兼容而不得不重新编译以适应版本。C++插件开发的发展历程可以参考下面这篇文章从暴力到NAN再到NAPI——Node.jsNativeModule开发模式变革N-API介绍N-API是node8.3的一个新的实验性特性。node10正式启用,以下是官网的描述N-API(字母N的发音,后接API)是构建原生Addons的API。它独立于底层JavaScript运行时(exV8),并作为Node.js本身的一部分进行维护。此API将在所有Node.js版本中保持稳定的应用程序二进制接口(ABI)。它旨在将Addons与底层JavaScript引擎的更改隔离开来,并允许为一个版本编译的模块无需重新编译即可在更高版本的Node.js上运行。插件是使用标题为C++插件的部分中概述的相同方法/工具构建/打包的。唯一的区别是本机代码使用的API集。不使用V8或Node.jsAPI的原生抽象,而是使用N-API中可用的函数。N-API是用于构建本机扩展的API。它不依赖于JavaScript运行时(如v8),而是作为Node.js自己构建的一部分运行。在Node.js中,此API将作为应用程序二进制接口(ABI)保持稳定。它的目的是让插件可以直接与底层的JS引擎交互,并允许它们只编译一次,而不必为每个新版本的Node重新编译。这个插件的构建、打包和使用与普通的C++插件相同。唯一的区别是这组API调用Node.js原生对象,而不是使用v8或Node.jsAPI的原生抽象。win环境相关准备如下方法一:全局安装windows-build-tools、node-gyp和node-pre-gyp-githubnpminstall--global--productionwindows-build-toolsnpminstall-gnode-gyp在顺序npminstall-gnode-pre-gyp-githubwindows-build-toolswindows环境下,node-gyp工作必须工具node-gypc++扩展编译工具node-pre-gyp-github二进制包分发工具node-pre-gyp实现中github解决部分使用环境缺少c++编译工具的问题。例如,在tag以slim和alpine结尾的节点镜像上运行的容器中安装后,需要设置相关的环境变量。具体可以参考node-pre-gyp-github方法二:安装dockerforwindows,具体安装方法可以参考官网在n-api扩展模块中编写代码。可以参考官方中文文档和官方示例(node10)。binding.gyp文件可以参考本页所列模块的binding.gyp。.官方的例子是使用node_api.h头文件。在最新的node12预览版中,可以使用新增的node_api.h引用的js_native_api.h头文件。与node_api.h相比,js_native_api.h中写的c++扩展不能使用nodejs的一些特性。目前发现不能直接调用的函数有Buffer对象、获取任务队列、异步操作等。目的是将js标准API与node-specificAPI隔离,以减少耦合,详情请参阅此PR。这是我写的例子,传送门:https://github.com/zhouzhi3859/napi_example克隆后,在文件目录下运行npminstall后,会看到除了node_modules和package-lock.json之外,还有更多的绑定文件夹包含直接从github下载的.node结尾的文件,不需要本地编译。在当前项目目录下在上面第一个环境中发出以下命令运行,win编译发布:npmrunbuildnpmrunpackage在上面第二个环境中npmrunpublish:dockerpullnode//cannotusetagstoslim和alpine的图像在最后,这些图像缺少C++扩展编译环境dockerrun-it-v$pwd:/root--namenapi_example_build-w/rootnodebash//进入容器,在容器中执行以下命令npmrunbuildnpmrunpackagenpmrunpublish然后退出容器,就可以按照正常的npm模块发布流程发布写好的c++扩展
