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:
- Node.js, selanjutnya akan disebut
node
- Compiler
c/c++
; misalnyagcc
;g++
diperlukan jika kita ingin mengkompilasi kodec++
. Tulisan ini menggunakang++
.
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!