擁抱 Node.js 8.0,N-API 入門極簡例子

程式猿小卡_casper發表於2019-02-15

本文摘錄自《Nodejs學習筆記》,更多章節及更新,請訪問 github主頁地址。歡迎加群交流,群號 197339705

N-API簡介

Node.js 8.0 在2017年6月份釋出,升級的特性中,包含了N-API。編寫過或者使用過 node擴充套件的同學,不少都遇到過升級node版本,node擴充套件編譯失敗的情況。因為node擴充套件嚴重依賴於V8暴露的API,而node不同版本依賴的V8版本可能不同,一旦升級node版本,原先執行正常的node擴充套件就編譯失敗了。

這種情況對node生態圈無疑是不利的,N-API的引入正是試圖改善這種情況的一種嘗試。它跟底層JS引擎無關,只要N-API暴露的API足夠穩定,那麼node擴充套件的編寫者就不用過分擔憂node的升級問題。

如何使用N-API

先強調一點,N-API並不是對原有node擴充套件實現方式的替代,它只是提供了一系列底層無關的API,來幫助開發者編寫跨版本的node擴充套件。至於如何編寫、編譯、使用擴充套件,跟原來的差不多。

本文會從一個超級簡單的例子,簡單介紹N-API的使用,包括環境準備、編寫擴充套件、編譯、執行幾個步驟。

備註:當前N-API還處於試驗階段,官方文件提供的例子都是有問題的,如用於生產環境需格外謹慎。

1、環境準備

首先,N-API是8.0版本引入的,首先確保本地安裝了8.0版本。筆者用的是nvm,讀者可自行選擇安裝方式。

nvm i 8.0
nvm use 8.0複製程式碼

然後,安裝node-gyp,編譯擴充套件會用到。

npm install -g node-gyp複製程式碼

建立專案目錄,並初始化package.json

mkdir hello & cd hello # 目錄名隨便起
npm init -f複製程式碼

2、編寫擴充套件

建立hello.cc作為擴充套件的原始檔。

mkdir src
touch src/hello.cc複製程式碼

編輯hello.cc,輸入如下內容。

#include <node_api.h>

// 實際暴露的方法,這裡只是簡單返回一個字串
napi_value HelloMethod (napi_env env, napi_callback_info info) {
    napi_value world;
    napi_create_string_utf8(env, "world", 5, &world);
    return world;
}

// 擴充套件的初始化方法,其中 
// env:環境變數
// exports、module:node模組中對外暴露的物件
void Init (napi_env env, napi_value exports, napi_value module, void* priv) {
    // napi_property_descriptor 為結構體,作用是描述擴充套件暴露的 屬性/方法 的描述
    napi_property_descriptor desc = { "hello", 0, HelloMethod, 0, 0, 0, napi_default, 0 };
    napi_define_properties(env, exports, 1, &desc);  // 定義暴露的方法
}

NAPI_MODULE(hello, Init);  // 註冊擴充套件,副檔名叫做hello,Init為擴充套件的初始化方法複製程式碼

3、編譯擴充套件

首先,建立編譯描述檔案binding.gyp

{
  "targets": [
    {
      "target_name": "hello",
      "sources": [ "./src/hello.cc" ]
    }
  ]
}複製程式碼

然後,執行如下命令進行編譯。

node-gyp rebuild複製程式碼

4、呼叫擴充套件

未方便呼叫擴充套件,先安裝bindings

npm install --save bindings複製程式碼

然後,建立app.js,呼叫剛編譯的擴充套件。

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

console.log( addon.hello() );  // world複製程式碼

執行程式碼,由於N-API當前尚處於Experimental階段,記得加上--napi-modules標記。

node --napi-modules app.js複製程式碼

輸出如下

{"path":"/data/github/abi-stable-node-addon-examples/1_hello_world/napi/build/Release/hello.node"}
world
(node:6500) Warning: N-API is an experimental feature and could change at any time.複製程式碼

相關連結

N-API:nodejs.org/api/n-api.h…

C++ Addons:nodejs.org/api/addons.…

相關文章