Kode minimal untuk membuat sebuah Node-4.x Addon dengan NAN-2.x

Node.js memungkinkan kita untuk memanggil shared library  (yang disebut addon dan ditulis dengan c/c++) dari baris kode javascript. Maksud dari tulisan ini adalah untuk memberikan pengalaman singkat perjalanan ke dunia native. Mudah-mudahan setelah ini pembaca akan kembali tertarik mendalami dunia native. Tulisan ini dibuat singkat untuk menimbulkan pertanyaan, sehingga diskusi dapat terjadi.

Di tulisan ini, kita akan membuat sebuah addon sederhana dengan kode seminimal mungkin. Penggunaan addon sederhana dari tulisan ini adalah sebagai berikut:

var addon = require('./');
addon.halo('Joni');
// 'Halo Joni!'

Peralatan yang diperlukan adalah:

  1. Node.js, selanjutnya akan disebut node
  2. Compiler c/c++; misalnya gcc; g++ diperlukan jika kita ingin mengkompilasi kode c++. Tulisan ini menggunakan g++.

Node.js dapat dipasang lewat nvm (https://github.com/creationix/nvm: nvm adalah node version manager yang memungkinkan kita memasang banyak versi runtime node dan memilih versi tertentu untuk menjalankan suatu baris kode javascript).

$ nvm install 4

nvm belum terpasang? Memasang nvm sangat mudah. Untuk memasang nvm kita dapat menggunakan curl :

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.29.0/install.sh | bash

atau wget:

wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.29.0/install.sh | bash

Pastikan nvm terpasang:

$ nvm version
0.26.1
$ nvm ls
-> v4.2.1
$ nvm use 4
Now using node v4.2.1 (npm v2.14.7)

Selanjutnya pastikan compiler g++ terpasang:

$ g++ --version
g++ (Debian 5.2.1-17) 5.2.1 20150911
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE

Jika belum terpasang, sebagai pengembang yang baik ada baiknya kita memasang paket build-essential dari lumbung.

$ sudo apt install build-essential
$ g++ --version
g++ (Debian 5.2.1-17) 5.2.1 20150911
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE

Setelah mesin kita terpasang node dan g++, maka kita akan mulai menulis kode.

Silakan singsingkan lengan baju!

Langkah pertama yang dilakukan adalah membuat direktori kerja:

$ mkdir halo
$ cd halo

Kemudian inisialisai direktori tersebut untuk dijadikan sebagai modul node.

$ npm init

Jawab pertanyaan wajibnya saja. (Jika punya banyak waktu bisa memikirkan nama modul dan deskripsi yang pas).

Is this ok? (yes)

Jika kita menjawab yes untuk pertanyaan di atas (Kalo aku sih YES!). Maka di direktori halo tersebut akan terbentuk berkas package.json, yang berisi:

{
  "name": "halo",
  "version": "1.0.0",
  "description": "Halo",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
  },
  "keywords": [
    "wait",
    "promise"
  ],
  "author": "Dhi Aurrahman <diorahman@rockybars.com>",
  "license": "MIT",
  "devDependencies": {}
}

Kemudian kita pasang modul NAN (https://github.com/nodejs/nan). Modul NAN adalah pustaka yang membantu pengembang modul native untuk punya abstraksi universal untuk berbagai versi node/V8. NAN juga memiliki beberapa macro yang membuat kode kita mudah dibaca.

Di direktori halo,

$ npm install nan --save

Setelah itu berkas pertama yang akan kita buat adalah binding.gyp. Berkas ini adalah Makefile-nya modul node yang memiliki kode native (butuh dikompilasi).

Buat berkas binding.gyp dengan isi sebagai berikut:

{
    "targets": [
        {
            "include_dirs": ["<!(node -e \"require('nan')\")"],
            "target_name": "Halo",
            "sources": [
                "halo.cc"
            ],
        },
    ],
}

Kemudian kita buat berkas halo.cc

#include <nan.h>

NAN_METHOD(Halo) {
    // baris kode berikut tentu tidak merefleksikan prinsip `seminimal mungkin`, 
    // tapi untuk kemudahan dibaca
    auto nama = Nan::To(info[0]).ToLocalChecked();
    auto sapa = Nan::New("Halo ").ToLocalChecked();
    auto pesan = v8::String::Concat(sapa, nama);
    info.GetReturnValue().Set(pesan);
}

NAN_MODULE_INIT(Init) {
    // Ingat module.exports di node?
    Nan::Export(target, "halo", Halo);
}

NODE_MODULE(Wait, Init)

Kemudian jalankan kembali npm init,

$ npm init

Trik ini dilakukan untuk menambahkan beberapa entri di package.json yang dibutuhkan untuk membangun addon secara otomatis. Silakan periksa berkas package.json, perhatikan apa saja yang berubah!

Setelah itu panggil perintah:

$ npm install

Maka secara sulap, addon akan dibangun.

Jika tidak ada galat (semoga ada galat ya! Jika tidak galat, ya tidak belajar!), maka akan terbentuk berkas Halo.node di direktori build/Release.

Untuk lebih praktis, sunting bagian main di package.json dari index.js menjadi build/Release/Halo.

Sehingga bagian tersebut di package.json menjadi:

{
  ...
  "description": "Halo",
  "main": "build/Release/Halo"
  ...
}

Saatnya mencoba modul kita!

Jalankan node REPL, dan tambahkan baris kode seperti di bawah ini:

$ node
> var addon = require('./');
> addon.halo('Joni');
Halo Joni

Selamat mencoba!

The following two tabs change content below.
Tukang kue

Latest posts by Dhi Aurrahman (see all)

Dhi Aurrahman

Tukang kue

Leave a Reply

Your email address will not be published. Required fields are marked *