Bienvenidos sean a este post, continuemos con los paquetes.
En el post anterior comentamos porque los modulos que instalemos los denominamos paquetes principalmente para no confundir con lo que son los modulos, y tambien mencionamos que node.js posee un algoritmos que nos permite buscar el modulo necesario entre todos los paquetes instalados, con esto podemos decir que al momento de recibir un require, import o import() el lenguaje se encarga de buscar hacia adelante en el archivo de sistemas desde el directorio donde se ejecuto la instruccion, este buscara por los directorios node_modules un paquete que satisfaga el nombre del modulo informado en alguna de las instrucciones anteriores.
Vamos a suponer que tenemos un archivo llamado foo.js en el siguiente path:
/home/david/projects/notes/foo.js
Y si nosotros hicieramos un llamado de require o import solicitando un modulo con el identificador bar.js, y vamos a suponer que poseemos la siguiente estructura:

Como mencionamos antes, la busqueda comenzara desde el nivel de foo.js por lo tanto node.js comenzara a buscar desde aqui por un archivo o directorio llamado bar.js conteniendo un modulo identificado con ese nombre, en este post mencionamos como hacer que un directorio actue como un modulo o paquete, asi que ahora buscaremos en el directorio mas cercano a foo.js y en todo directorio anterior pero no ira a los directorios posteriores a node_modules, ya que la transversabilidad ira siempre para arriba y no mas abajo, en general los paquetes de terceras partes tienen una finalizacion de nombre con .js pero en su gran mayoria no por lo tanto es tipico que se utilice un require(‘bar’), y por lo general es muy tipico que los paquetes de terceros contengan un archivo package.json y algunos archivos de javascript.
Este es uno de esos casos tipicos, el identificador del paquete sera bar y esto hara que node.js encuentre un directorio llamado bar en uno de los directorios node_modules y acceda al paquete desde ese directorio, este acto de busqueda nos muestra que node.js soporta paquetes de instalacion anidada, esto implica que un paquete puede depender de otros modulos que posea su propio directorio node_modules, vamos a suponer que este depende del paquete fred lo cual ocasiona que el administrador de paquetes instale dicho paquete en el siguiente path:
/home/david/projects/notes/node_modules/bar/node_modules/fred
Con esto nuestra estructura de directorio puede quedar de la siguiente manera:

En este caso cuando un archivo de javascript en el paqute bar usa un require(‘fred’) la busqueda por los modulos comienza en:
/home/david/projects/notes/node_modules/bar/node_modules
Donde lo encontrara pero supongamos que el adminstrador detecta que otros paquetes de notes utiliza a fred este procedera a instalarlo en:
/home/david/projects/notes/node_modules/fred
Porque como mencionamos el algoritmo al buscarlo hacia arriba lo encontrara en ese lugar, asi que podemos decir que el anidado de los directorios node_modules es arbitrariamente profundo, aunque si bien el administrador trata de imponer una jerarquia plana, para nosotros puede ser mas necesario que tengamos un anidado profundo, veamos el porque.
El algoritmo de resolucion de identificadores de paquetes node.js nos permite instalar dos o mas versiones de un mismo paquete, volvamos al hipotetico proyecto notes donde si miramos a la imagen anterior veremos que fred esta tanto en el paquete notes como en el paquete express, mirando al algoritmo sabemos que fred es el adecuado para cada paquete instalado localmente, lo usual es que el administrador detecte las dos instancias de fred e instale solo uno pero supongomas que el paquete bar requiere laa version 1.2 de fred mientras que express requiere la version 2.1 de fred, en estos casos el adminsitrador instalara ambos paquetes debido a las diferencias de versiones, por lo tanto podemos decir que para la version 1.2 estara en:
/home/david/projects/notes/node_modules/bar/node_modules
Y la version 2.1 estaara en:
/home/david/projects/notes/node_modules/express/node_modules
Esto ocasiona que cada paquete posea su propia version de fred, ocasionando que ambos funcionen correctamente sin saber que existe otra version del paquete fred, y esto es bueno para la aplicacion pero que sucede si necesitamos usarlas entre multiples aplicaciones? bueno, pasemos al siguiente tema.
Paquetes globales
Cuando hablamos sobre npm en este post, vimos que entre las opciones disponibles nos permitia instalar un paquete de forma global permitiendo que este accesible para cualquier aplicacion, una de las formas de encontrar los paquetes es mediante NODE_PATH, esta variable es similar a PATH, ya que nos permitira almacenar directorios en los cuales realizar la busqueda de los paquetes, pero este no es recomendable porque si al momento de ser utilizado en otro equipo o entorno la gente que lo utiliza si no establece a esta variable puede ocasionar que la aplicacion no funcione porque no encuentra los paquetes, lo mas recomendable es que todo el listado de paquetes se encuentre bien aclarado en package.json dado que el algoritmo se encargara de buscarlo por nosotros y a su vez este mismo algoritmos volvio obsoleta a esa variable, tambien disponemos de tres opciones mas:
- $HOME/.node_modules
- $HOME/.node_libraries
- $PREFIX/lib/node
Este tambien nos puede ser util porque $HOME representa el path del home del usuario y $PREFIX es el path donde esta ubicado el binario de node.js, aunque lo mas recomendado es que se mantenga siempre de forma local porque al igual que comentamos antes si necesitamos mover la aplciacion a otro equipo o entorno si lo tenemos de forma local solamente debemos pasar el directorio donde se encuentre, en cambio de forma global puede ocasionar que alguno de los paquetes se instale en una ubicacion desconocida provocando que al pasar la aplicacion no funcione por este faltante, por esta razon muchos no recomiendan el usar paquetes de forma global.
En resumen, hoy hemos visto como node.js busca paquetes dentro del sistema cuando pedimos la implementacion de alguno mediante require, import o import(), hemos visto como nos habilita la posibilidad de tener varias versiones de un paquete y no se interfieran entre ellas, asi como tambien podemos hacerlo de forma global pero tambien comentamos porque no es recomendable esta ultima opcion, espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
