Sabías que en node.js puedes escribir módulos no solamente en javascript, si no también en c++/nativos ?, Pues en este pequeño post quisiera compartirles como construir y depurar un modulo sencillo sobre Visual Studio Code. Dado que este tema es bastante extenso y mi objetivo en este caso es resaltar las bondades del IDE, para aquellos que quieran indagar mas y seguir investigando, les dejos un enlace a uno de los cursos mas completos que he visto: https://github.com/workshopper/goingnative. Así que sin mas preámbulos manos a la obra.
- primero cree un nueva carpeta en la ubicación que usted desee, luego ábrala desde visual studio code
- File > Open folder
- Luejo presione Ctrl + ñ, o active la terminal desde el menú View > Integrated Terminal, como se muestra en la imagen a continuación
- para crear el archivo package.json de nuestra aplicación y donde registraremos las dependencias de nuestro modulo, ejecute el siguiente comando :npm init
- Instale Nan, node-gyp como dependencias de desarrollo ejecutando el siguiente comando : npm i –save-dev nan node-gyp
- y bindings como dependencia del modulo: npm i –save bindings
- nuestro archivo package.json debe verse mas o menos así
-
Nan(«Native abstraction for nodejs»): dado que el Api de v8 se esta actualizando constantemente, Nan es una interfaz que nos permite estandarizar la codificación de nuestros módulos, y evita que nos preocupemos por la versión del engine sobre la cual se ejecutaran. solo aplica para módulos nativos
-
node-gyp: es una herramienta de linea de comandos escrita en nodejs sobre gyp(Generate Your Project), que nos facilita el proceso de compilación generación de nuestro módulos nativos.
- Luego de que el proceso de instalación de dependencias, haya culminando satisfactoriamente, dentro del folder raíz, cree un archivo: binding.gyp: Este archivo es un array de targets, en donde para cada target/modulo, definiremos: en la propiedad target_name su nombre,en sources: que archivos c/c++ serán compilados y en include_dirs: los archivos .h o header de librerías externas requeridas por nuestro modulo (por ejemplo nan, boost, dlib,lib.xml, window.h etc. ) . Dicho esto nuestro archivo quedará así:
- Creé entonces el archivo mymodule.cc:
- This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
#include <nan.h> using namespace v8; //definimos nuestra función (suma=>nombre) NAN_METHOD(suma){ //validamos los parametros de entrada que le enviaremos desde js if(!info[0]->IsNumber() && !info[2]->IsNumber() ){ //si los argumentos son invalidos arrojamos una exception Nan::ThrowError("argumentos invalidos"); return; } //obtenemos los valores double a = info[0]->NumberValue(); double b = info[1]->NumberValue(); Local<Number> result = Nan::New(a + b);//calculamos la suma info.GetReturnValue().Set(result);//finalmente retornamos el resultado } NAN_MODULE_INIT(Init) { //exportamos la función suma Nan::Set(target, Nan::New("suma").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(suma)).ToLocalChecked()); } NODE_MODULE(mymodule, Init) - para compilarlo, ejecute en la terminal el siguiente comando:.
.\node_modules\.bin\node-gyp configure
.\node_modules\.bin\node-gyp build
- Luego de compilar, node-gyp creo una carpeta llamada build, y dentro genero el archivo : …build\Release\mymodule.node:
- para probar nuestro modulo cree un archivo index.js con el código a continuación y ejecútelo, bien sea desde la terminal con el comando node index.js o desde visual studio code:
- This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
/*para cargar el modulo nativo dentro de nuestro archivo js podemos usar el pauqte bindings que instalamos al principio o especificar la ruta completa de donde esta el archivo .node generado*/ //froma 1 const mymodule = require("bindings")("mymodule");//el .node no es necesario //forma 2 //const mymodule = require("./build/Release/mymodule");//el .node no es necesario const sum = mymodule.suma(2,2); console.log("El resultado de la suma es :", sum);//mostramos el resultado - para la depuración, sigas las instrucciones a continuación:
- paso 1: abra el archivo mymodule.cc, y agregue un punto de interrupción.Haga click derecho sobre cualquier linea en el área donde esta el punto rojo en la imagen y seleccionar la opción en el menú desplegable add breakpoint.
- paso 2: habilite el modo depuración haciendo click
- paso 3: Haga click sobre la opción Add configuratión en el menú desplegable
- Agregue al archivo launch.json la siguiente configuración:
- «type: cppvsdbg»: usar el visual studio debugger
- «program»: definir el path de donde se encuentra nuestro archivo node.exe
- «externalConsole»: abrir la interactive console de node en otra terminal por fuera de visual studio code
- En el modo de depuración, en el menú desplegable DEBUG seleccione la opción Debug Native Addon, luego haga click sobre el botón ejecutar, ubicado al lado izquierdo color verde, y se abrirá la consola de node.exe:
- En la consola interactiva copie el siguiente código y presione la tecla enter :
const mymodule = require(«./build/Release/mymodule»);
mymodule.suma(2,2);
Notará que el punto de interrupción será ejecutado:
Esto es todo por el momento, espero que este tips les sea de gran utilidad.
Saludos
Henry Ruiz