Una de las cosas que he hecho últimamente, es instalar un servidor con una Raspberry Pi v2 en casa para acceder desde fuera usando OpenVPN. Pero para que fuera accesible siempre a través del mismo dominio necesitaba una forma de actualizar el registro DNS y quería hacerlo con mi propio dominio y no con ddns, no-ip o similares así que hice un programa en node que hiciera esto por mi aprovechando la API de OVH.
Requisitos
- Node instalado (y el gestor de paquetes de node npm).
- Aunque lo haremos aquí se supone que ya tienes tú archivo
package.json
creado.
Preparativos
Creamos el archivo package.json
:
# npm init
Cabecera de nuestro ejecutable
En el script node que queremos que funcione como si de un binario se tratara deberemos de emular a los bash scripts e incluir los caracteres Shebang que caracteriza a los scripts ejecutables, haciendo llamar al interprete nodejs en este caso.
#! /usr/bin/env node
Definiendo cuál será nuestro ejecutable
Los archivos package.json
tienen varios parámetros, todos muy bien documentados. Y entre ellos hay dos que son los que nos interesan bin
y preferGlobal
.
Bin
Bin nos permite definir todos los “symlinks” (enlaces simbólicos) que creará npm en /usr/local/bin/
al archivo node que le definamos. Por ejemplo suponiendo que queramos que dos archivos de nuestro paquete tengan enlaces simbólicos y suponiendo que se van a llamar nodeinout
(un programa que basicamente todos los parámetros que le pasemos los devuelve uno por uno) y otro nodecat
que lee y saca al stout todo el contenido de un archivo de texto. Por supuesto que los programas no existen y si existen es fruto de la casualidad pues es solo para alimentar el ejemplo.
Para que estos comandos existan debemos de modificar nuestro package.json actual:
{
"name": "node-cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "Gabriel Trabanco Llano <gtrabanco@fwok.org> (http://gabi.com.es)",
"license": "ISC"
}
Y AÑADIR por ejemplo después de license (en cualquier sitio entre los {}
“corchetes”):
"license": "ISC",
"bin": {
"nodeinout": "inout.js",
"nodecat" : "nodecat.js"
}
Como véis es muy sencillo, si tuvieramos el archivo javascript (.js
) en otro directorio tan solo deberíamos añadir la ruta relativa desde el archivo package.json
.
PreferGlobal
El parámetro preferGlobal
es de tipo booleano e indica que es un programa de línea de comandos que preferiblemente debe instalarse de manera global (npm install -g
), lo cual según la documentación no impedirá que los usuarios puedan instalarlo localmente pero si falla habrá un dato más ahí a la hora de hacer comprobaciones. Lo añadimos igualmente en cualquier parte dentro de {}
(los corchetes), por ejemplo:
"license": "ISC",
"preferGlobal": true,
"bin": {
"nodeinout": "inout.js",
"nodecat" : "nodecat.js"
}
Documentación (man
)
Otro de los parámetros posibles es man
que permite definir la ruta a un archivo de documentación que luego estará disponible para nuestro programa desde el terminal haciendo man nombre_programa
.
No voy a explicar más al respecto, si quieren ver como funciona pueden ver [el cliente que he hecho][dyndns] para lo de los DNS en github. Deben fijarse en el package.json y en el directorio man.
Después según la documentación oficial sobre este parámetro (man
), deben de tener en cuenta varias cosas a la hora de nombrar el archivo. Mejor usen la documentación en npmjs (en inglés).
El formato del archivo de documentación pueden verlo en el pie de página. 1
Probando que funciona
Cuando estéis desarrollando vuestro programa, si queréis probar que crea los enlaces correctamente podéis usar el comando:
# npm link
Si después deseáis quitar los enlaces que os ha creado:
# npm unlink
Ejemplo
Como ejemplo, podéis ver la aplicación de línea de comandos que hice para actualizar el registro DNS. Se llama DynHost, si preferís, podéis verlo directamente en el registro npmjs.
Conclusiones
Es sencillo crear programas de línea de comandos con node, pero hay que tener en cuenta estas cosas ya que varía un poco de un desarrollo normal de una página web.
Por otro lado, si queréis que vuestro script acepte parámetros os remito nuevamente a mi proyecto en github y veáis un ejemplo real y funcionando de yargs, una excelente librería que he decidido usar para esta labor.