搜尋
首頁web前端js教程如何進行Node.js擴充開發?前置知識分享

如何進行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…

如何進行Node.js擴充開發?前置知識分享

##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…

如何進行Node.js擴充開發?前置知識分享

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

> process.versions
{
  node: '18.0.0',
  v8: '10.1.124.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-如何進行Node.js擴充開發?前置知識分享

如何進行Node.js擴充開發?前置知識分享

安装依赖项

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

3-如何進行Node.js擴充開發?前置知識分享

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

手动安装步骤如下:

1.安装node-gyp

npm install -g node-gyp

2.安装Visual Studio Build Tools

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

如何進行Node.js擴充開發?前置知識分享

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

如何進行Node.js擴充開發?前置知識分享

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环境变量

如何進行Node.js擴充開發?前置知識分享

更新npm配置,

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

从hellow world开始

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

如何進行Node.js擴充開發?前置知識分享

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

如何進行Node.js擴充開發?前置知識分享

执行示例文件中的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…

如何進行Node.js擴充開發?前置知識分享

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

如何進行Node.js擴充開發?前置知識分享

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

环境配置

vsCode安装c++ intelliSense扩展应用

1如何進行Node.js擴充開發?前置知識分享

配置.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…

1如何進行Node.js擴充開發?前置知識分享

其他形式的扩展 napi-rs

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

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

1如何進行Node.js擴充開發?前置知識分享

类似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 教程

以上是如何進行Node.js擴充開發?前置知識分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

在Quartz中如何在任務開始前發送通知?在Quartz中如何在任務開始前發送通知?Apr 04, 2025 pm 09:24 PM

如何在Quartz中提前發送任務通知在使用Quartz定時器進行任務調度時,任務的執行時間是由cron表達式設定的。現�...

在JavaScript中,如何在構造函數中獲取原型鏈上函數的參數?在JavaScript中,如何在構造函數中獲取原型鏈上函數的參數?Apr 04, 2025 pm 09:21 PM

在JavaScript中如何獲取原型鏈上函數的參數在JavaScript編程中,理解和操作原型鏈上的函數參數是常見且重要的任�...

微信小程序webview中Vue.js動態style位移失效是什麼原因?微信小程序webview中Vue.js動態style位移失效是什麼原因?Apr 04, 2025 pm 09:18 PM

在微信小程序web-view中使用Vue.js動態style位移失效的原因分析在使用Vue.js...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器