讲师中心 微信公众号
AI工具推荐 视频效率加速

如何进行Node.js扩展开发?前置知识分享

雨婷大大_2364

雨婷大大_2364

发布时间:2022-08-29 20:04:57

|

2609人浏览过

|

来源于掘金社区

转载

如何进行node扩展开发?下面本篇文章就来介绍一下开发node.js扩展的前置知识,带你入门node.js扩展开发,希望对大家有所帮助!

如何进行Node.js扩展开发?前置知识分享

为什么要开发Node.js扩展

1.Node.js不适合cpu密集型业务,开发扩展使用libuv线程池做异步计算

2.需要更高的执行性能,例如使用c++、Rust等比javascript更高效的语言

3.已有c++库,直接封装成Node.js扩展提供给javascript调用,避免重复开发

4.通过javascript无法实现的能力,开发扩展增强Node.js能力

什么是Node.js扩展

Node.js扩展是文件扩展名为.node的二进制文件,本质上是动态链接库,可以理解为改了名的.dll或.so文件,可以被require加载

Node.js module官方文档 nodejs.cn/api/modules…

1.png

Node.js扩展的三种形式

扩展类型 基本描述 Node.js版本变化时改代码 Node.js版本变化时重新编译
直接写C++ 直接引用v8、libuv等库进行开发 是 是
NAN 使用NAN(Native Abstraction for Node.js)进行开发 否 是
N-API 使用node-addon-api进行开发 否(ABI版本需一致) 否(ABI版本需一致)
直接写C++代码开发插件,当Node.js版本变化时引用的v8、libuv等库的版本可能发生变化,这些三方库的api也可能会变化,导致需要修改代码

NAN方式开发插件,引用nan.h需要在Node.js版本变化时重新编译

N-API方式调用Node.js稳定的二进制ABI接口(Application Binary Interface),只要ABI版本号一致就不需要重新编译复制代码

我们可以从Node.js官网历史版本下载页面,NODE_MODULE_VERSION看到Node.js版本与ABI版本的对应关系,nodejs.org/zh-cn/downl…

2.png

或者执行process.versions.modules查看ABI版本;process.versions查看相关配套版本:

> process.versions
{
  node: '18.0.0',
  v8: '10.1.124124.8-node.13',
  uv: '1.43.0',
  zlib: '1.2.11',
  brotli: '1.0.9',
  ares: '1.18.1',
  modules: '108',
  nghttp2: '1.47.0',
  napi: '8',
  llhttp: '6.0.4',
  openssl: '3.0.2+quic',
  cldr: '41.0',
  icu: '71.1',
  tz: '2022a',
  unicode: '14.0',
  ngtcp2: '0.1.0-DEV',
  nghttp3: '0.1.0-DEV'
}

我们来看下官方的Node.js扩展代码示例:github.com/nodejs/node… 对于N-API方式来说,c语言对应示例代码中的napi案例,c++对应示例代码中的node-addon-api案例,引用的头文件不同。

3-1.png

3.png

安装依赖项

首先,需要安装依赖,按官方的说法可以使用windows-build-tools安装所有依赖。 nodejs.cn/api/n-api.h…

3-2.png

但是,公司内网环境一直安装失败,按照文档尝试改了各种参数还是失败,可能是公司内网环境问题。如果你也遇到类似问题,可以尝试手动安装依赖。 github.com/felixrieseb…

手动安装步骤如下:

1.安装node-gyp

npm install -g node-gyp

2.安装Visual Studio Build Tools

可以参考node-gyp文档中的下载链接和步骤进行安装github.com/nodejs/node…

4.png

安装完成后更新npm配置,例如我安装的版本号是2022

5.png

npm config set msvs_version 2022

安装headers,头文件和Node.js版本是对应的,如果用nvm等工具切换过Node.js版本,请重新安装

node-gyp install --dist-url=http://mirrors.tools.huawei.com/Node.js/

此步骤会将node_api.h等头文件下载到本地,按Node.js版本号区分目录,例如:

C:\Users\z00443016\AppData\Local\node-gyp\Cache\18.0.0\include\node

配置IDE时会需要用到,当前可以忽略,后续的文章会再介绍具体配置

3.安装python

官网下载地址:www.python.org/downloads/

安装完成后将python和python/Scripts/目录加入到Path环境变量

6.png

更新npm配置,

npm config set python D:\runtime\python复制代码

从hellow world开始

以c++开发为例,复制官网示例到本地。github.com/nodejs/node…

用于自动切换项目中适合的node 版本
用于自动切换项目中适合的node 版本

根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。

下载

7.png

执行npm install会自动调用node-gyp编译,生成build/Release/hello.node的目标文件,这个文件就是最终被js引用的扩展包,可以被require调用。

8.png

执行示例文件中的hello.js,会调用hello.cc中定义的hello方法输出'world'。

var addon = require('bindings')('hello');

// 或者直接require hello.node文件
// var addon = require('./build/Release/hello.node');

console.log(addon.hello()); // 'world'

如需重新编译,可以执行node-gyp rebuild,或者执行node-gyp help了解其他命令

至此,一个Node.js扩展demo就完成了。

抛出问题

Node.js使用非阻塞io的方式,在一个线程内可以异步处理多个任务,但是如果有一个cpu密集型的任务一直在处理,那么就会阻塞其他任务,响应时间变长。

Node.js官网的解释如下 nodejs.cn/learn/the-n…

9.png

开发Node.js扩展是解决问题的方式之一,最终使用什么方式去解决问题,需要基于我们对Node.js的理解,找到最佳实践。在上述场景中,我们可以使用libuv提供的线程池来异步处理这些cpu消耗较高的任务,从而不会阻塞其他任务的执行。

10.png

当然了,web server并不适合处理cpu密集型任务,如果这个cpu密集型的任务调用频繁且耗时较高,就需要考虑从业务维度拆分,将任务挪到消息队列消费端执行。

环境配置

vsCode安装c++ intelliSense扩展应用

11.png

配置.vscode/c_cpp_properties.json,主要在includePath中配置好headers路径

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:\Users\${userName}\AppData\Local\node-gyp\Cache\18.0.0\include\node",
                "D:\tool\nvm\v18.0.0\node_global\node_modules\node-addon-api"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "cStandard": "c17",
            "cppStandard": "c++17",
            "intelliSenseMode": "windows-msvc-x64"
        }
    ],
    "version": 4
}

配置.vscode/launch.json,完成调试配置就可以断点调试了。

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "c++ launch",
            "type": "lldb",
            "request": "launch",
            "program": "D:\runtime\nodejs\node.exe",
            "args": ["${workspaceFolder}/src/hello.js"],
            "stopAtEntry": true,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "lldb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

asyncWork扩展开发

可以参考官网示例,在项目中的Execute方法中添加自定义代码,不妨动手一式。github.com/nodejs/node…

node-gyp构建工具

node-gyp是Node.js扩展的构建工具,依赖python和Visual Studio Build Tools,基于google的gyp(Generate Your Projects)工具,chromium、v8等项目也在使用gyp构建。还可以使用CMake.js等工具进行编译构建。

npm config set msvs_version 2022
npm config set python D:\runtime\python

在package.json中定义"gypfile": true,执行npm install时会自动调用ndoe-gyp执行build操作。github.com/nodejs/node…

{
  "name": "hello_world",
  "version": "0.0.0",
  "description": "Node.js Addons Example #1",
  "main": "hello.js",
  "private": true,
  "dependencies": {
    "bindings": "~1.2.1",
    "node-addon-api": "^1.0.0"
  },
  "scripts": {
    "test": "node hello.js"
  },
  "gypfile": true
}

node-pre-gyp预构建

由于编译是基于操作系统和硬件平台进行的,node-gyp构建生成的.node动态链接库不能跨平台,所以通常我们在使用Node.js扩展时以依赖包的形式引入项目,当执行npm install时,自动调用node-gyp生成当前环境可用的.node扩展包。

上述方式需要即时编译,无疑会拖慢npm install过程。于是就出现了node-pre-gyp预构建工具,直接从仓库下载当前环境可用的Node.js扩展包。

以Xprofiler为例,根据当前系统、硬件平台、Node.js的ABI版本生成下载地址,定义在package.json的binary字段:

"binary": {
    "module_name": "xprofiler",
    "module_path": "./build/binding/{configuration}/{node_abi}-{platform}-{arch}/",
    "remote_path": "./v{version}/",
    "package_name": "{module_name}-v{version}-{node_abi}-{platform}-{arch}.tar.gz",
    "host": "https://github.com/X-Profiler/xprofiler/releases/download"
},

mirrors.tools.huawei.com/xprofiler/v…

12.png

其他形式的扩展 napi-rs

rust语言非常火爆,在Node.js开发领域也大有成为基础设施的趋势。比如,Node.js作者的新项目Deno就是用rust语言开发的;使用swc开发的编译工具替代Babel提升性能;rust支持编译成Webassembly,在前后台都能执行,具有很好的前景。

很多公司对rust语言十分重视,例如下图中的TOP公司已经成为rust基金会白金会员,用实际行动支持rust语言的发展。foundation.rust-lang.org/

13.png

类似c++项目使用napi开发Node.js扩展,社区出现了napi-rs项目来支持rust语言开发Node.js扩展。github.com/napi-rs/nap…

直接调用动态链接库 node-ffi

FFI(Foreign Function Interface)语言交互接口,用一种编程语言写的程序能调用另一种编程语言写的函数,基本上成熟的编程语言都支持。使得我们可以在Node.js中直接调用c/c++、go、rust等语言编译生成的动态链接库,示例如下: github.com/node-ffi/no…

例如libmylibrary.dll或libmylibrary.so动态链接库的代码,c语言中的.h头文件描述:

double    do_some_number_fudging(double a, int b);
myobj *   create_object();
double    do_stuff_with_object(myobj *obj);
void      use_string_with_object(myobj *obj, char *value);
void      delete_object(myobj *obj);

js中使用ffi进行对应描述:

var ffi = require("ffi");

var MyLibrary = ffi.Library('libmylibrary', {
  "do_some_number_fudging": [ 'double', [ 'double', 'int' ] ],
  "create_object": [ myobjPtr, [] ],
  "do_stuff_with_object": [ "double", [ myobjPtr ] ],
  "use_string_with_object": [ "void", [ myobjPtr, "string" ] ],
  "delete_object": [ "void", [ myobjPtr ] ]
});

然后,就可以在js中调用了:

var res = MyLibrary.do_some_number_fudging(1.5, 5);
var fun_object = MyLibrary.create_object();

if (fun_object.isNull()) {
    console.log("Oh no! Couldn't create object!\n");
} else {
    MyLibrary.use_string_with_object(fun_object, "Hello World!");
    var fun = MyLibrary.do_stuff_with_object(fun_object);
    MyLibrary.delete_object(fun_object);
}

更多node相关知识,请访问:nodejs 教程!

热门AI工具

更多
讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

相关专题

更多
Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

40

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

20

2026.10.22

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

20

2026.10.22

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

0

2026.10.22

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

20

2026.10.22

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

20

2026.10.22

Golangci-lint安装与入门教程
Golangci-lint安装与入门教程

本专题讲解Golangci-lint的安装、初始化、基础命令和首次代码检查,覆盖本地环境、Docker及多平台用法,帮助Go开发者快速上手。

20

2026.10.22

PHP2Shell高危漏洞修复教程
PHP2Shell高危漏洞修复教程

PHP2Shell漏洞是什么,哪些PHP版本和运行环境会受到影响,服务器应该如何检测与修复?本专题提供版本自查脚本、Linux与Docker升级命令、PHP-FPM和Apache排查步骤,以及修复验证、临时缓解和应急响应方案。

140

2026.10.22

剧云人物设定与关系管理教程
剧云人物设定与关系管理教程

本专题介绍剧云人物设定与关系管理,讲解角色小传、性格职业、人物目标、背景资料和关系网络的创建及维护方法。

20

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
快速入门Node.JS全套完整版
快速入门Node.JS全套完整版

共83课时 | 13.5万人学习

nodejs开发基础教程
nodejs开发基础教程

共15课时 | 4.9万人学习

JavaScript设计模式视频教程
JavaScript设计模式视频教程

共28课时 | 6.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn