导语:当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的替代,目前处于实验阶段。