post thumbnail

Node.js y Express: Como crear módulos

Publicado Por: Oscar González, El 02/12/2013


Detalles del Curso:

Dificultad: Aprendiz

Duración: 10 min


En este capítulo les voy a hablar sobre como crear sus propios módulos de Node.js. Este tutorial no tiene que ver necesariamente con Express sino con Node directamente. Pero antes de continuar, un poco de teoría.

Si han estado siguiendo esta serie se deben haber dado cuenta que hacemos uso constante de sentencias como: module.exports = holaMundo;, var miModulo = require('./MiModulo');, var express = require('express');. Estas sentencias son invocaciones a módulos.

Un módulo es un archivo con código, o también puede ser un archivo compilado de Node.js. En estos archivos declaramos clases, propiedades, métodos, entre otros. Normalmente estos son privados a otros módulos, es decir, no se puede acceder a ellos desde otros archivos. Entonces te preguntarás: "Pero a lo largo de esta serie hemos estado utilizando módulos que pueden acceder a código de otros módulos", y eso es porque hemos estado utilizando inconscientemente el API CommonJS que viene incluido con Node.


CommonJS

CommonJS protege la privacidad de los módulos evitando exponerlos a un contexto global y revelando cada uno, solo a los otros módulos que estén conectados con el mismo.

Esto se logra empleando el patrón "Módulo". Éste consiste en dos partes: Requerir el módulo y exportar el módulo. Veámoslo con un ejemplo:

Cuando creamos un proyecto con Express encontramos el en app.js el siguiente código entre otras sentencias:

var http = require('http'); // 1

http.createServer(app).listen(app.get('port'), function(){ // 2
  console.log('Express server listening on port ' + app.get('port'));
});
  1. Creamos primero una referencia al módulo http;
  2. Y hacemos uso de él a través de la variable http que creamos.

Ahora para exportar un módulo hacemos lo siguiente:

var miClase = function () { // 1

    this.miAtributo;

    this.unMetodo = function () {

        // hacer algo

    }

    return this;
}

module.exports = miClase; //2
  1. Definimos la clase;
  2. Y la exportamos.

Los módulo no necesariamente tienen que se clases. Ya veremos eso.


Creando módulos propios

Entonces empecemos a crear nuestro módulo.

Primero necesitamos crear un archivo que contenga al módulo.

// HealthComponent.js

var health = 10;

var getHit = function (amount) {

    health -= amount;

}

module.exports.health = health; // 1
module.exports.getHit = getHit;
  1. Para exponer los módulos usé el mismo nombre de la variable o método por convención. Podia haber usado cualquier nombre.

Como podemos observar no fue necesario usar una clase, pero tal vez habría sido más útil ya que solo habría tenido que exportar la clase y no cada propiedad y método por separado.

Ahora vamos a otro archivo a importar nuestro módulo y utilizarlo.

// app.js

var myHealthComponent = require('./HealthComponent.js');

console.log('Vida actual: ', myHealthComponent.health);
console.log('Fuiste atacado, tus vidas disminuyeron a: ' + myHealthComponent.getHit(1));

Esto debería imprimir por consola:

$ Vida actual: 10
$Fuiste atacado, tus vidas disminuyeron a: 9

Otras maneras de requerir módulos

Si convirtiéramos "HealthComponent.js" en una clase se exportaría de la siguiente manera:

// HealthComponent.js

var HealthComponent = function (initialHealth) {

    this.health = initialHealth;

    this.getHit = function (amount) {

        this.health -= amount;

    }

    return this;
}

module.exports = HealthComponent;

Ahora podría requerirla de dos maneras distintas:

var HealthComponent = require('./HealthComponent.js');

var myHealthComponent = new HealthComponent(10);

En esta varsión importo la clase primero y luego la instáncio con un valor de vida inicial de 10.

var myHealthComponent = require('./HealthComponent.js')(10);

Y en esta la importo y creo la instancia en una sola línea.

Direcciones de componentes

Hasta ahora hemos requerido módulos que son del API de Node (como "http") o módulo que están en direcciones relativas ("./HealthComponent.js" o "../HealthComponent.js")

También podemos requerir módulos por su dirección absoluta:

var modulo = require('home/components/HealthComponent.js');

Si quisiéramos requerirlo solo por el nombre var health = require("HealthComponent"); tendríamos que colocarlo en la carpeta de módulos de node (node_modules).

Por ejemplo si nuestro módulo que están en "/home/components/HealthComponent.js", requiriera un módulo llamado "Personaje" y lo importara de la siguiente manera var health = require("Personaje");, este tendría que esta en "node_modules"

Node busca al módulo en los siguientes directorios en este orden:

  1. /home/components/node_modules/Personaje.js
  2. /home/node_modules/Personaje.js
  3. /node_modules/Personaje.js

De no encontrarlo en el primero, pasa al segundo y así sucesivamente hasta llegar a "node_modules". Si no lo encuentra en el último, entices retornará un error "Cannot find module".

Usando carpetas como módulos

Supongamos que queremos separar los controladores en varias carpetas en nuestro proyecto, algo así:

Project
--Controllers
----home
------index.js
------other.js
----login
----users

En la carpeta home podríamos tener un archivo index.js. Esto le dice a Node que este archivo debe correrse primero. También podría tener la extensión .node (index.node). Y este luego requerir a otro módulo dentro de la misma carpeta.

// index.js

var o = require("./other.js");

Incluso podríamos reemplazar index.js con un archivo package.json que cumple la misma función, éste contendría el siguiente código:

{
  "name": "Home",
  "main": "other.js"
}

Conclusión

Con esto damos por terminado el tutorial del día de hoy. Espero que ahora tengas un mejor entendimiento de como funcionan los módulos en Node.js y te atrevas a crear los tuyos.

Cualquier duda o comentario, como siempre déjalo en la sección correspondiente más abajo. Con gusto atenderé tus inquietudes.

Hasta la próxima.


¿Te ha gustado esta publicación?

Compártela:

Por Oscar González

Conoce más sobre este autor aquí


comments powered by Disqus