La editorial O’Reilly permite la descarga gratuita de su libro What is Node? un muy buen recurso para poder iniciarnos en Node.js. Libro escrito por Brett McLaughlin y publicado en Julio de 2011.
Descarga: What is Node?
Node.js HispanoLa editorial O’Reilly permite la descarga gratuita de su libro What is Node? un muy buen recurso para poder iniciarnos en Node.js. Libro escrito por Brett McLaughlin y publicado en Julio de 2011.
Descarga: What is Node?
Sin duda muchos de los artículos referentes a node.js tanto en español como en inglés van directamente relacionados a demostrar/explicar como crear aplicaciones como mejorar tu ritmo de trabajo o cuan concurrente y rápido es node.js.
Pero muy pocos se detienen a explicar o indagar un poco más acerca de una de las herramientas más importantes dentro del “workflow” de node.js:
npm;
Contrariamente a las creencias de muchos, “npm” no es una abreviación para “Node Package Manager”. - npm FAQ
¿No me crees? Mira lo que dice wikipedia. Según Isaac Schlueter:
El proyecto “npm” es nombrado luego de la utilidad de la linea de comandos, la cual fue organicamente selecionada para ser fácilmente escrita por un programador de mano derecha usando un teclado US QWERTY, terminando con el dedo del anillo derecho en una posición para escribir
-seguido de parámetros o “flags”. Esta utilidad de linea de comandos siempre es en minúsculas… - npm FAQ
A pesar de la complicada e interesante descripción del origen de “npm”, definitivamente npm es el director de la orquesta cuando se refiere a el manejo de dependencias o módulos en node.js, los uso más comunes son para:
Es la herramienta perfecta y necesaria en cuando a manejo de dependencias se refiere.
Desde la versión 0.6.3 npm viene integrado en el proceso de instalación de node.js, así que no tienes que instalarlo por separado. Si aún estas con una versión menor a esta considera en actualizar o trabaja con un administrador de versiones como n ó nvm, los cuales te permiten tener instaladas múltiples versiones de node en tu maquina de desarrollo lo cual es muy útil si trabajas en diferentes proyectos o modulos.
A continuación te listaré una serie de comandos que son muy útiles y que posiblemente tu desconozcas:
Para acceder a cada uno de ellos simplemente haz en tu linea de comandos: npm <comando>.
npm init
Sin duda mi favorita, esta utilidad te permite crear, modificar y generar un package.json válido. Su uso principal función es agregar y no borrar elementos en tu archivo. Su funcionamiento es seguir una serie de preguntas, simple de usar.
¿Necesitas de una aplicación más especializada? Grunt.js es tu amigo
npm search <nombre-del-modulo|palabra-clave>:
Te permite buscar en el registro de npm, algun modulo acerca de la palabra clave que tu seleccionaste. Si bien npm tiene muchas opciones que lo pueden hacer perfecto, este aspecto es un poco “delicado” y “complicado”. Hay ciertos sitios web que hacen un poco mejor el trabajo de search.npmjs.org o te ofrecen una serie de herramientas y recursos, para hacer de esto un proceso menos doloroso, tales herramientas son:
npm info <nombre-del-modulo>
Muestra información en formato json acerca de <nombre-del-modulo>, útil cuando quieres saber versión actual y demás detalles acerca de un módulo:
> npm info express > npm info kronos > npm info <package-name>
npm ls, npm la, npm ll, npm listLista los paquetes que tienes actualmente instalados en un determinado directorio. En formato de tree:
bolt@0.1.2 /home/alejandromg/dev/bolt └─┬ bolt@0.3.2 ├── colors@0.6.0-1 ├── eventemitter2@0.4.8 └── redis@0.7.1
npm outdated
Su nombre es más que explicativo, busca si hay versiones más nuevas acerca de los modulos instalados en el directorio actual.
Genera algo como:
node-watcher@0.0.3 ./node_modules/node-watcher current=0.0.2 request@2.9.202 ./node_modules/request current=2.9.153 nano@2.1.0 ./node_modules/nano current=1.3.0
Por lo tanto un npm update o npm up es necesario, pero antes asegúrate que tu actualización no vaya a crear errores por nueva API o nuevos métodos.
npm link:
Sin duda una de las herramientas más útiles y más controversiales. Por diseño, npm no va instalar una sola versión de un módulo “x” en tu computador, en cambio va a instalarlo y hacerlo disponible solo en el directorio en el que ejecutaste: npm install mi-modulo.
Por ejemplo: express.
Para instalarlo haces: npm install -g express, con esto tienes la utilidad de linea de comandos para poder luego hacer:
express misuperapp
Lo cual te va a generar algo como:
create : misuperapp ...blah blah dont forget to install dependencies: $ cd misuperapp && npm install
Luego de hacer cd misuperapp, necesitas instalar las dependencias, pero que sucede si no tienes acceso a internet en ese momento o no quieres volver a descargar express, en este caso puedes hacer npm link express, para crear un link simbólico a la versión global de express:
$ cd misuperapp && npm link express ./node_modules/express -> /usr/local/lib/node_modules/express
Con esto ya tienes la habilidad de usar la versión global de express sin necesidad de descargarla de nuevo.
Importante: Como dije anteriormente por diseño, cuando haces npm install npm instala una copia local en misuperapp, lo cual es lo mejor, ya que te ayuda a mantener un control mejor de dependencias y debugabilidad. Además un par de KB en tu disco duro no hacen mal. Por lo tanto aunque sea útil, no es una práctica recomendada.
¿Pero, y entonces para que la menciono? Pues aparte de la utilidad indicada anteriormente, hay una aun más importante, pero un poco más complicada de explicar y especifica para aquellos que escriben módulos, ya que atraves de npm link puedes crear una referencia global al módulo que escribes y hacer pruebas con tus dependencias. Esto esta mucho mejor explicado mejor en npm tricks.
Para terminar con npm link, como bien diría Isaacs en #node.js :
“En producción, tu VM puede estar limitada a un servicio, o espacio en disco, en este caso,
npm linkno es tan malo. Pero por el amor a la debugabilidad y alta disponibilidad, no lo hagas en otros escenarios, por que symlinks son dolorosos en producción…” - Referencia
El contrario a npm link es npm unlink.
npm shirnkwrap
A diferencia de npm link, shrinkwrap es una herramienta con más utilidad para aquellos que desarrollan módulos, en pocas palabras shirnkwrap “bloquea” las versiones que utilizas en determinada aplicación, de esta manera te aseguras que las versiones que van a ser posteriormente instaladas en la cadena de distribución sean las mismas que utilizaste en el desarrollo de tu módulo o aplicación. Este comando generara un nuevo archivo donde estara el árbol o esquema con las versiones que deben ser instaladas al momento de instalar tu módulo. Más información
Y muchos más:
npm home <modulo>: Muestra el sitio web del módulo, si existe.npm prune, npm rm: prune elimina paquetes que no se encuentran en el package.json pero si en el folder node_modules, a diferencia de rm que elimina el modulo que pasas como parámetro e.g: npm rm expressnpm help folders: Explica como funciona la instalación de módulos, muy interesante.npm view <módulo> <detalle>, npm show: Muestra información especifica acerca de , por ejemplo:npm view nhouston author va a mostrar “Alejandro Morales <mi_correo@electronico.com>”, detalle puede ser cualquiera de los campos del package.jsonnpm config list: muestra la configuración que esta siendo utilizada por npm.npm help: muestra toda la ayuda referente a npm.npm faq: Preguntas Frecuentesnpm es perfecto ( si, es una conclusión ). Claro existen “ciertos” ( pocos ) problemas, pero para un usuario “regular” no deberían ser un problema. Son cosas low-level. Y que a la mayoría de nosotros no vamos a enfrentar.
Por cierto, he tomado oficialmente la responsabilidad en la traducción de la documentación de npm al español, así que si quieres aportar en el proceso clona mi fork y enviame tus cambios por github, de esa manera podemos generar más información en español.
¿No te gusta? npm es la navaja suiza en cuanto a “package-managers” del mundo de la programación, no solo eso te brinda un sin número de beneficios además el gran soporte por parte de la comunidad en general, lo hacen el más seguro y confiable.
¿No te convencí? ¿Faltó algo? Bueno, existen otros package-managers para node.js como:
Particularmente no he usado ninguno así que te sigo recomendando npm.
npm faq)Autor de éste Artículo
Alejandro Morales, Hondureño, Estudiante universitario, Astrolover, HTML5, CSS3, node.js aficionado. Gran observador de la conducta humana. Conocido en la internet y IRC como “alejandromg”. Puedes seguirlo en twitter, o ver en lo que esta trabajando en github, o en forrst.
En el siguiente video se muestra como podemos integrar Cloud9 ( IDE Web ) con nuestras aplicaciones desarrolladas en Node.js y así poder publicarlas en una cuenta de Nodester.
servidor.js:
var port = process.env.C9_PORT || 13087;
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(port);
LordZero000, Canal de Youtube
disclaimer: Este articulo posee muchas opiniones personales, así que pardon me de antemano.
Sin duda cuando una nueva tecnología como node.js es mostrada al mundo, como desarrollador te preguntas: “¿Y hace esto, hace aquello?, ¿Es lo suficientemente rápido?.” “Mmm no, no lo hace, pero si hago esto y para lo otro puedo una crear una extensión”.
Ya ha sucedido, paso(a) con jQuery, WordPress, etc., que mejor ejemplo que la n cantidad de lightbox’s para jQuery o los plugins para facebook en WordPress, hay gustos y sabores para todo lo que tu quieras. Solo piensa un momento y veras que es cierto.
Bueno, pues a mi me gusta pensar que así surgió NPM (Node Package Manager), como una herramienta para unir los esfuerzos individuales de los miembros de la comunidad, y hacer de la misma, la comunidad más interesante y activa que personalmente yo conozco. Claro, agregado a otros factores que ayudaron y han ayudado a hacer más atractivo el trabajar con node.js.
A inicios de esta semana, estaba buscando un xml parser (no pregunten para que), y me costo un poco encontrar uno que estuviera suficientemente documentado y que realizara lo que yo necesitaba, pero me di cuenta de cuan difícil era decidirme por alguno. En adicción, soy de las personas que leen el código, van a github, o lo instala localmente, que trata de entender como funciona, estoy entre github y search.npmjs.org y así, voy y vengo. TL-DR. De igaul forma así como surgió NPM Docs, humildemente escrita por su servidor.
Pero este articulo no se trata de lo que hice, si no de lo que me encontré con el registro de NPM y pensé en como mejorar esta situación, o al menos “evangelizar” de un estilo unificado para escribir módulos.
NPM cuenta con cerca de 7350 módulos y sigue en constante crecimiento, y lo más interesante es que la mayoría cuenta con una organización y estructura totalmente diferente, desde el package.json hasta el esqueleto del folder contenedor, elegidos totalmente al azar. No lo llamaría un desorden, pero si una forma no muy agradable de los mismos. Así que luego de esta larga introducción déjeme hablarles de Como crear módulos para node.js
Ya hace días, cree una módulo exactamente para esto: Kronos, kronos inicializa una repo, con la estructura mínima y necesaria para la creación de un modulo. Kronos lo puedes installar con npm install -g kronos.
Una estructura modelo seria como sigue:
Nombre del módulo
\
|- lib/
\
|- PROJECTNAME.js
|- bin/
\
|- BINFILE
|- examples/
|- test/
|- index.js
|- package.json
|- README.md
Esta es una estructura que define el diseño promedio de los módulos escritos en|para node.js, cerca del 80% esta conformado de esta manera o un modelo similar.
Si te fijas en el diagrama, puedes ver esta compuesto de cuatro carpetas, dentro de lib se encuentra el *.js principal, no en el directorio raiz, sino que esta dentro de lib, aqui van tambien cada uno los *.js que hacen funcionar tu módulo. Si tu estas escribiendo un app para la CLI pones dentro de bin tu ejecutable. Y las otras carpetas son obvias: test y ejemplos.
Algo muy interesante es el package.json, NPM lo ha convertido en archivo imprescindible en el desarrollo de las aplicación pues es a través de él que tu se instalan las dependencias de tú aplicación. Sin duda una lectura recomendada es este cheatsheet, quien explica como debe estar escrito este documento. Pero siguiente con nuestro ejemplo, el package.json de kronos es el siguiente:
{
"name":"kronos",
"version":"0.0.2",
"description":"A dead simple scheme maker to initialize and setup your new project",
"author":"Alejandro Morales",
"preferGlobal": "true", // Instalar global
"dependencies":{
"commander":"0.5.x",
"mkdirp":"0.2.x"
},
"bin": {
"kronos": "./bin/kronos"
},
"main": "./lib/kronos",
...
}
Aquí están especificados todas la información necesaria que NPM toma al momento de publicarla e instalarla.
La parte pública, la más importante de lo que haces, puede que no seas un gran escritor o que detestes escribir documentación, pero es de alta relevancia que lo hagas. Créeme.
Documentos:
module.exportsUn módulo, no necesariamente necesita ser del dominio público, puede que lo que tu quieras es organizar tu código en varios archivos, y ocupas hacer un “require” debes en cuando, o tu módulo cumple una utilidad muy especifica en la aplicación. Es ahí donde las buenas practicas entran en acción. El uso de module.exports y el scope en el que ejecutas tu extensión|módulo.
CommonJS, es un esfuerzo por parte de la comunidad para estandarizar el empaquetamiento de librerías en javascript, comúnmente conocidas como módulos. Los módulos son escritos en cumplimiento de este estandar, proveyendo gran portabilidad a otros frameworks como narwhal o inclusive los navegadores.
TJ Holowaychuk - Mastering Node
Y es así, como module.xxxxx surge. Un ejemplo muy sencillo, (escrito a propósito para este articulo), es un módulo con operaciones básicas de un Array númerica: max, min y unique.
module.exports es el punto de referencia que es llamado cuando tu haces var http = require('http'), en este caso, node.js busca al objeto exports o module.exports exponiendo todos los métodos y funciones contenidas en ella.
Los siguientes ejemplos son validos:
module.exports.PI = Math.PI; module.exports.SQRT2 = Math.SQRT2;
También:
var miFuncion = function(){
....
}
module.exports = miFuncion;
Ahora miremos las diferentes formas de escribir módulos. La primer forma que vamos a ver es la que sigue: Simple y sin muchas complicaciones, variable = module.exports = valor|función
// utilidades.js
var max = module.exports.max = function(array){
var a = array.sort();
return a[a.length-1];
}
var min = module.exports.min = function(array){
var a = array.sort();
return a[0];
}
var unique = module.exports.unique = function(array){
return array.filter(function(v, i, a) {
return a.lastIndexOf(v) === i; })
.sort();
}
Este es el método más común y mas rápido. Como te has de haber dado cuenta este código correría tanto en el server como en el browser, claro realizando algunos cambios y haciéndola un poco más atractiva:
(function(ut){
ut.max = function(array){
var a = array.sort();
return a[a.length-1];
};
ut.min = function(array){
var a = array.sort();
return a[0];
};
ut.unique = function(array){
return array.filter(function(v, i, a) {
return a.lastIndexOf(v) === i; })
.sort();
}
return ut;
})(typeof exports === "undefined" ? utilidades = {} : exports);
Este método utiliza algo llamado Immediately-Invoked Function Expression (IIFE) y particularmente es la que más me gusta. Además corre en tu navegador ( copy/paste). Todavía hay 2 formas más, pero voy explicar la más sencilla:
var ut = function(array){
this.array = array;
}
ut.prototype.max = function(){
var a = this.array.sort();
return a[a.length-1];
};
ut.prototype.min = function(){
var a = this.array.sort();
return a[0];
};
ut.prototype.unique = function(){
return this.array.filter(function(v, i, a) {
return a.lastIndexOf(v) === i; })
.sort();
};
module.exports = exports = ut;
Este último método utiliza prototype, como pueden ver estamos extendiendo las propiedades del Array inicial, obteniendo los metodos. En este caso es necesario inicializar el objeto a evaluar con new METHOD(Array). Este método es muy útil. Si hago unrequire('./utilidades') me loguea [Function]. A excepción de los dos anteriores que me muestran lo siguiente:
{ max: [Function],
min: [Function],
unique: [Function] }
Las 3 tendrán las mismas utilidades. Las primeras dos se pueden utilizar como sigue:
// superapp.js
var u = require('./utilidades'); // asumiendo que esta en el mismo dir
var test = [0,3,4,5,4,3,4,2];
console.log(u.max(test)); // => 5
console.log(u.min(test)); // => 0
console.log(u.unique(test)); // => [0,2,3,4,5]
Y en la tercera:
// superapp.js
var u = require('./utilidades');
var test = new u([0,3,4,5,4,3,4,2]);
console.log(test.min()) //=> 0
console.log(test.max()) //=> 5
console.log(test.unique()); // => [0,2,3,4,5]
Como puedes, ver la tercera utiliza un método más interesante y definitivamente más útil, ya que te ocupa unos cuantos caracteres menos y es más entendible.
En todos los ejemplos, utilice un forma distinta de exportar el código externo, mediante module.exports, cada uno en un contexto diferente. Cada uno tiene sus ventajas y desventajas, pero si hay algo que tienes que tener cuidado es en el de respetar tunamespace para evitar conflictos y bugs indeseables. Elije nombres y descriptores aceptables y únicos. Con aceptables me refiero, a nombres que no vayan a entrar en conflicto, o que son keywords de javascript.
Si escribes módulos para el dominio público, ten en cuenta, la documentación (README) correcta de la misma, un package.json bien escrito, y un código limpio. Recuerda: Don’t Repeat Yourself.
Alejandro Morales, Hondureño, Estudiante universitario, Astrolover, HTML5, CSS3, node.js aficionado. Gran observador de la conducta humana. Conocido en la internet y IRC como “alejandromg”. Puedes seguirlo en twitter, o ver en lo que esta trabajando en github, o en forrst.