本文摘錄自《Nodejs學習筆記》,更多章節及更新,請訪問 github主頁地址。歡迎加羣交流,羣號 197339705。javascript
Node.js 8.0 在2017年6月份發佈,升級的特性中,包含了N-API。編寫過或者使用過 node擴展的同窗,很多都遇到過升級node版本,node擴展編譯失敗的狀況。由於node擴展嚴重依賴於V8暴露的API,而node不一樣版本依賴的V8版本可能不一樣,一旦升級node版本,原先運行正常的node擴展就編譯失敗了。html
這種狀況對node生態圈無疑是不利的,N-API的引入正是試圖改善這種狀況的一種嘗試。它跟底層JS引擎無關,只要N-API暴露的API足夠穩定,那麼node擴展的編寫者就不用過度擔心node的升級問題。java
先強調一點,N-API並非對原有node擴展實現方式的替代,它只是提供了一系列底層無關的API,來幫助開發者編寫跨版本的node擴展。至於如何編寫、編譯、使用擴展,跟原來的差很少。node
本文會從一個超級簡單的例子,簡單介紹N-API的使用,包括環境準備、編寫擴展、編譯、運行幾個步驟。git
備註:當前N-API還處於試驗階段,官方文檔提供的例子都是有問題的,如用於生產環境需格外謹慎。github
首先,N-API是8.0版本引入的,首先確保本地安裝了8.0版本。筆者用的是nvm
,讀者可自行選擇安裝方式。npm
nvm i 8.0
nvm use 8.0複製代碼
而後,安裝node-gyp
,編譯擴展會用到。json
npm install -g node-gyp複製代碼
建立項目目錄,並初始化package.json
。api
mkdir hello & cd hello # 目錄名隨便起
npm init -f複製代碼
建立hello.cc
做爲擴展的源文件。bash
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爲擴展的初始化方法複製代碼
首先,建立編譯描述文件binding.gyp
。
{
"targets": [
{
"target_name": "hello",
"sources": [ "./src/hello.cc" ]
}
]
}複製代碼
而後,運行以下命令進行編譯。
node-gyp rebuild複製代碼
未方便調用擴展,先安裝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.…