NodeJS C/C++ Addon Geliştirme

NodeJS ile backend geliştirmek artık çok daha yaygın ve kullanışlı fakat bazı mümkün olmayan fonksiyon ve durumlar bulunmaktadır. NodeJS, native katmanlar ile bize C++ ile addon geliştirip kullanabilme imkanı sunmaktadır. Bu sayede NodeJS tarafında mümkün olmayan bir çok şeyi hem çok hızlı hem de mümkün kılabiliriz.

Çok basit bir NodeJS C++ eklentisi geliştirelim

Başlamadan önce sürekli kullanacağımız bazı terminolojileri bir göz atalım.

node.gyp: Cross-platform native eklentileri compile edip, native bir node eklentisine çevirmek için kullanılan bir CLI tool.

node-addon-api: NodeJS için bulunan C++ header dosyaları. C++ ile NodeJS arasında bulunan bir abstract katman diyebiliriz.

binding.gyp: Geliştirdiğimiz eklentiyi compile etmek için kullandığımız config dosyası. Hangi lib'ler dahil edilsin, eklenti ismi, header dosyaları vs..

İlk olarak bir klasör oluşturalım. Bu klasör projemizin root dosyası olsun. Root dosyamız içinde 'npm init' komutu ile package.json dosyamızı oluşturalım.

Eklenti geliştirebilmek için gerekli olan katmanı 'npm install --save node-addon-api' komutu ile kuralım.

Compile etmek için gerekli olan CLI tool'u 'npm install -g node-gyp' komutu ile kuralım.

'binding.gyp' adında config dosyamızı oluşturalım. Compile ederken 'node-gyp' bu config dosyasına bakacaktır. Aşağıda bulunan config dosyasını aynen 'binding.gyp' dosyamıza kopyalayalım.

{
    "targets": [{
        "target_name": "native",
        "sources": [
            "library.cc"
        ],
        'include_dirs': [
            "<!@(node -p \"require('node-addon-api').include\")",
        ],
        "libraries": [],
        'dependencies': [
            "<!(node -p \"require('node-addon-api').gyp\")",
        ],
        'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
    }]

'binding.gyp' dosyamızı inceleyecek olursak;

target_name: Geliştirdiğimiz eklentinin ismi olacaktır. Compile ettiğimizde 'native.node' olarak bir çıktı verecektir. Bu çıktı './build/Release' klasörü içinde bulunacaktır.

source: Compile edeceğimiz C/C++ dosyası. (Birden fazla bulunabilir)

include_dirs: Compile ederken C/C++ içinde kullandığımız tüm kütüphaneleri buraya da dahil etmek zorundayız.

C++ eklenti dosyamız:

#include <iostream>
#include <napi.h>

Napi::String FirstAddonFunction(const Napi::CallbackInfo &info) {
    Napi::String text = Napi::String::New(info.Env(), "My First Addon");
    return text;
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
    exports.Set("firstAddonFunction", Napi::Function::New(env, FirstAddonFunction));
    return exports;
}

NODE_API_MODULE(MODULE, Init);

NodeJS dosyamız:

const lib = require('./../build/Release/native');
console.log(lib.firstAddonFunction());

Dosyalarımızı oluşturduktan sonra compile etmeliyiz. 'node-gyp build' komutu ile native node dosyamızın oluşturulmasını sağlayalım. Compile olduktan sonra root klasörümüz içinde build adında bir klasör oluşacaktır. 'build/Release' içinde config dosyasmızda belirttiğimiz eklenti isminde bir node dosyası oluşacaktır.

'node index.js' komut ile eklentimiz çalıştıralım.

>node index.js
My First Addon

Umarım bu yazı kendi eklentinizi daha ileri seviyede geliştirmenize yardımcı olur :)

Örnek olarak geliştirdiğim eklentiyi inceleyebilirsiniz.

https://github.com/emreyalvac/cpp-hexgenerator