導語:當Javascript的性能遭遇瓶頸,或者須要加強Javascript能力的時候,就須要依賴native模塊來實現了。javascript
平常工做中,咱們常常須要將原生的Node.js模塊作爲依賴並在項目中進行使用。下面有個列表,你可能對它們的名字很熟悉:css
一般,咱們開發原生Node.js模塊包括但不只限於如下緣由:html
Node.js Addons是動態連接的可共享對象,由C/C++編寫而成。能夠在Node.js中經過require()
方法進行調用,使用起來像調用Node.js普通模塊同樣。 —— 來自Node.js官方文檔java
這意味着若是處理得當的話,模塊調用者使用由C/C++編寫的原生模塊的方式和由Node.js編寫的模塊同樣。想要編寫Node.js addons,你須要瞭解一些基本知識:node
推薦閱讀這些資料。python
下面我以一個常見的動態規劃問題-青蛙跳臺階爲例子來講明如何建立一個原生的Node.js模塊。青蛙跳臺階描述爲:一隻青蛙一次能夠跳上一級臺階,也能夠跳上2級臺階,求該青蛙跳上n級臺階的共有多少種跳法?linux
首先建立一個frog_jump.cc原生文件,.cc的意思是c with class,擴展名也能夠是.cpp。Google Style Guide建議使用.cc,那麼此處仍是以.cc作爲擴展名吧。代碼以下:c++
#include <node.h> #include<vector> /** * Native method, calculate all ways frog jump to a target stair. */ int climbStairs(int n) { std::vector<int> dp(n); dp[1] = 1; dp[2] = 2; for (int i = 3; i <= n; i ++ ) { dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; } /** * Export native method jumpTo */ void JumpTo(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::Isolate* isolate = args.GetIsolate(); // Check input type if (!args[0] -> IsNumber()) { isolate -> ThrowException(v8::Exception::TypeError( v8::String::NewFromUtf8(isolate, "Wrong arguments type!"))); } int value = climbStairs(args[0] -> NumberValue()); v8::Local<v8::Number> num = v8::Number::New(isolate, value); args.GetReturnValue().Set(num); } // init is entry point. void init(v8::Local<v8::Object> exports) { NODE_SET_METHOD(exports, "jumpTo", JumpTo); } NODE_MODULE(frog_jump, init)
對這段代碼的解釋:git
v8::
標誌來訪問v8的接口。訪問全部v8的類型,都須要使用v8::標誌一旦源代碼編寫完成,須要將它編譯成二進制的addon.node
文件,以後才能被Node.js require。爲了完成編譯操做,須要在項目的根目錄建立binding.gyp文件,裏面定義了Build的配置。binding.gyp的內容是一個JSON。github
{ "targets": [ { "target_name": "frog_jump", "sources": [ "frog_jump.cc" ] } ] }
編譯環境配置:
雖然npm內置了一個node-gyp版本,可是這個版本沒有開放給開發者進行調用。npm install的時候會調用它來進行編譯和安裝工做。所以,開發者想要調用node-gyp必須本身安裝一個全局的node-gyp版本。
$ npm install node-gyp -g $ node-gyp configure $ node-gyp build
運行node-gyp configure命令會生成一個跨平臺的build文件,unix環境會生成Makefile,windows環境會在build目錄裏面生成vcxproj。
運行node-gyp build命令會生成可被Node.js調動的addon.node二進制文件。
const frogJump = require('./build/Release/frog_jump'); frogJump.jumpTo(20); //青蛙跳到第20個臺階的全部方法
項目源代碼:frog-jump
nan,即Native Abstractions for Node.js。它基於Node.js API接口,兼容全部Node版本,目前的最佳實踐是基於nan來擴展原生模塊,而不是直接使用Node.js API。
N-API,Node官方推出的用來編寫原生Node擴展模塊,是V8和nan的替代,目前處於實驗階段。