Node.js: Modularizando
Nuestro index.js
actualmente luce así:
index.js
Como podemos notar en el mismo archivo se mezclan responsabilidades muy distintas. Si bien de momento index.js
es bastante simple es de esperarse que, conforme agreguemos las funcionalidades faltantes, el mismo crezca exponencialmente.
Debemos encontrar alguna de dividir el mismo en unidades cohesivas.
Modulos (ES6)
Antes que la especificación de javascript que hoy conocemos como ES6 (o ECMAScript 2015) no existía en js ninguna forma oficial de modularizar el código. Muchas librerías proveían implementaciones parciales (incompatibles entre si) que se volvieron de a poco estandares de-facto (CommonJS, RequireJS, AMD). ES6 tomó herramientas de dichos mecanismos (principalmente de CommmonJS) y las formalizó en la especificación del lenguaje.
Por qué modulos?
Tradicionalmente las aplicaciones javascript dividían su código entre distintos archivos los cuales eran concatenados al buildear la aplicación para producir un único archivo fuente. Esta práctica, si bien solucionaba el problema inmediato, era propensa a varios problemas:
- Era muy fácil generar colisiones de nombres entre archivos (por ejemplo: una misma variable global declarada dos veces con fines distintos).
- Conforme a la complejidad del sistema crecía multiples referencias al mismo archivo podían resultar en el mismo código siendo ejecutado varias veces (y en un estado duplicado).
Como solución a dichos problemas los sistemas de modulos introducen al modulo como una unidad aislada:
- Cada modulo corre posee entonces su propio scope lo que previene las colisiones de nombre.
- Cada modulo es efectivamente un singleton que puede ser importado varias veces en distintos momentos.
Links utiles
Refactorizando nuestra aplicación
Comenzaremos por definir una estructura de directorios donde colocaremos nuestros archivos.
src/backend
- aquí colocaremos todo el código perteneciente al backend (nodejs + express) de nuestra app. Moveremos nuestro archivoindex.js
a esta localización.src/backend/models
- aquí crearemos un archivo js por modelo que declaremos en mongoose.src/backend/routes
- crearemos un modulo que contendrá las distintas rutas de nuestra aplicación.
Primero modificaremos el archivo package.json
para referenciar a la nueva ubicación de nuestro index.js
package.json
Luego crearemos el archivo Post.js
en src/backend/models
y colocaremos en él la definición del schema.
src/backend/models/Post.js
Es importante notar lo siguiente:
- Necesitamos importar aquí al modulo mongoose ya que haremos uso de él inmediatamente después.
- Exportaremos el objeto
Post
de forma que pueda ser referenciado por otros modulos.
A continuación moveremos la configuración de nuestras rutas a un nuevo archivo llamado routes.js
. Ubicaremos el mismo en src/backend/routes
.
src/backend/routes/routes.js
En este caso en lugar de configurar nuestro objeto app
directamente procederemos a configurar, en cambio, un objeto router
el cuál exportaremos para usar mas tarde.
Es util notar que debido a que nuestras rutas hacen uso del objeto Post
deberemos importar el modulo Post.js
que habíamos creado antes.
Para finalizar, refactorizaremos nuestro index.js
para importar los modulos recién creados.
src/backend/index.js
import
TODO, hablar del algoritmo de resolucion de modulos
Luego es simplemente cuestión de reiniciar node (npm start
) y nuestro proyecto debería funcionar exactamente igual que antes. Pero con código mucho mas limpio!
GitHub
Como referencia dejamos el estado del proyecto en GitHub