Utilizar node-usb en versiones modernas de NodeJS y Electron

Ignacio Buioli
- 22/05/2017

Es cierto que Google ha apostado, estos últimos años, al desarrollo de WebUSB mediante el nuevo objeto de JavaScript navigator.usb, que estará disponible solo por medio de HTTPS y a partir de la versión 59 de Chrome. Por estos motivos el paquete de node-usb, a pesar de encontrarse desactualizado, sigue siendo de gran interés para desarrolladores de JavaScript que desean acceder al USB o al puerto Serial desde una WebApp.

¿Cual es el inconveniente con el paquete actual de node-usb? Que se encuentra generado con versiones antiguas de node.js y npm, con lo cual no lograr ejecutarse correctamente en aplicaciones de electron. Como ocurre habitualmente en node.js, es necesario hacer un rebuild de las dependencias para electron, para lo cual suelen utilizarse paquetes preparados como electon-rebuild. No obstante para el caso de node-usb dicho paquete (así como otras soluciones mediante node-gyp) no han dado resultados. Se decidió, por lo tanto, investigar opciones para lograr la instalación correcta de node-usb, principalmente porque la misma es dependencia de paquetes como node-serial.

Se sobrentiende que se encuentra instalada en la computadora una versión estable de node.js y npm. Ya con eso, lo primero y más recomendado, es hacer una instalación limpia y segura de electron, para lo cual recomiendo ampliamente el electron-quick-start proporcionado por los propios desarrolladores de electron. Una vez realizada la instalación, es conveniente ejecutarla mediante npm start para comprobar que la misma funcione correctamente. Debe aparecer una ventana con los números de versiones de Electron, Node y Chrome que se está utilizando en la app.

Ahora es momento de instalar nuestras dependencias, en este caso el paquete usb para node, una versión mejorada de node-usb. Para ello, ejecutaremos en nuestra terminal la instalación de las libs de las cuales depende (en el caso de Linux):

sudo apt-get install build-essential libudev-dev


A continuación podremos instalar el paquete usb en nuestra app de electron mediante npm:

npm install usb

 

Acá empiezan los problemas, al llamar la librería con la función require() es muy probable que nos salte un error en la consola con la siguiente estructura:

...was compiled against a different Node.js version using NODE_MODULE_VERSION XX.

This version of Node.js requires NODE_MODULE_VERSION XX.

Please try re-compiling or re-installing the module.

 

Nos van a recomendar hacer npm rebuild o npm install, pero para node-usb ninguna de las opciones, actualmente, son de utilidad. Necesitaremos hacer un rebuild manual. Primero, instalar node-gyp de forma global:

sudo npm install -g node-gyp

 

Cambiar al directorio de node-usb utilizando el siguiente comando:

cd `npm ls usb --parseable`

En ciertas situaciones puede producir un error y no mover al directorio, en tal caso debemos movernos manualmente o mediante el siguiente comando:

cd node_modules/usb

 

Entrar al archivo binding.gyp:

nano binding.gyp

Y modificar las propiedades de variables:

'variables': {
    'use_udev%': 1,
    'use_system_libusb%': 'false',
    'module_name': 'usb_bindings',
    'module_path': './src/binding'
  },

 

Finalmente, se hace un rebuild de forma manual con el siguiente comando:

HOME=~/.electron-gyp node-gyp rebuild --target=`npm view electron version` --arch=x64 --dist http://atom.io/download/atom-shell