Conjunto de tecnologías de JavaScript
La Historia
Entonces, tú y tu cofundador tienen esta genial idea para un negocio, ¿verdad?
Has estado agregando características en tu cabeza.
Frecuentemente, le preguntas a tus potenciales clientes sus opiniones, y todos ellos la aman.
Ok, entonces la gente la quiere. Hay hasta un poco de dinero para hacer. Y la única razón por la cual ellos no pueden obtenerla es porque no las has implementado—todavía.
Entonces, finalmente, te sientas un día y dices “¡Hagámoslo!”. Pronto, estás tratando de averiguar cómo aplicar la lógica de negocio de tu aplicación, la funcionalidad asesina que va a llevar adelante al producto: tienes una idea de cómo hacerlo, y ahora sabes que puedes hacerlo.
“¡Listo!¡Funciona!” dices. ¡Tu prueba de concepto es un éxito! Todo lo que queda por hacer es empaquetarlo en una aplicación web.
“Ok, hagamos el sitio”, dices.
Y entonces, te das cuenta de la verdad: necesitas elegir un lenguaje de programación; necesitas elegir una plataforma (moderna); necesitas elegir algunos frameworks (modernos); necesitas configurar (y comprar) espacio, base de datos y proveedores de alojamiento; necesitas una interfaz de administración; necesitas un sistema de permisos; necesitas un administrador de contenidos.
Tienes que tomar decenas y decenas de decisiones de arquitectura . Y quieres tomar las correctas: quieres usar tecnologías que te permitan desarrollo rápido, iteración constante, máxima eficiencia, velocidad, robustez y más. Quieres ser escueto, quieres ser ágil. Quieres usar tecnologías que te ayudaran a tener éxito en el corto-y largo-plazo. Y no son siempre fáciles de elegir.
“Estoy abrumado”, dices, mientras te vas sintiendo abrumado. Tu energía no es la misma de antes. Tratas de encajar las piezas, pero es demasiado trabajo.
Tu prueba de concepto se marchita y muere lentamente.
La Propuesta
Luego de abandonar toneladas de ideas de esta forma, decidí diseñar una solución. La llamo el proyecto ‘Init’ (Inicio)(ó init.js).
El corazón de la idea es tener un simple proyecto que inicie todos los demás, dejar que el desarrollador o el fundador técnico tomen esas decisiones al mismo tiempo y recibir una plantilla apropiada para empezar basada en esas decisiones. Se lo que van a decir los detractores, “Una solución no puede aplicarse a todos los problemas” (Odiadores odiarán). Y puede que estén en lo cierto. Pero podemos hacer nuestro mejor esfuerzo para crear una solución aproximada, y creo que Init se acerca bastante.
Para lograr mejor este objetivo, tenemos que tener algunas ideas claves en mente. Cuando estaba desarrollando Init, consideré:
- ComponentesLa modularización es una característica clave de cualquier sistema ya que te permite reusar componentes de software a través de distintos proyectos—lo cual es el principal objetivo de Init. Pero la modularización también viene con una “reemplazabilidad” por producto, la cual será nuestra mejor aliada a la hora de atacar varios tipos de problemas con “casi” la misma solución.
- Facilidad de DesarrolloPara algunos problemas, en algún lado hay una mejor solución escrita en [Brainf*ck](https://en.wikipedia.org/wiki/Brainfuck). ó jodecerebros). Pero implementar esa solución (en Brainf*uck) sería casi imposible de escribir, y mucho menos de leer. Te costaría tiempo y una enorme cantidad de esfuerzo. En general, deberías usar lenguajes y plataformas que hagan al desarrollo fácil, y no difícil para tí (o alguien que puede trabajar con él más tarde).
- ComunidadCualquier plataforma que elijas, asegúrate que tenga una gran comunidad, y una que te pueda ayudar con los problemas más comunes y con los que no lo son tanto. Recuerda: jQuery puede no ser la librería másrápida, la más limpia, o la más elegante—pero es un ganador sólo por su comunidad.
Teniendo estos objetivos en mente, voy a mostrarte como hice mis propias decisiones al crear Init.
En su núcleo, Init se aprovecha del paradigma ‘full-stack JavaScript’ (algunas personas se refieren a él, o a una parte de él, como el MEAN Stack). Al trabajar con este conjunto, Init es capaz de usar solamente un sólo lenguaje mientras crea un ambiente increíblemente flexible y con todas las funciones para desarrollar aplicaciones web. En resumen, Init te permite usar JavaScript no solamente para desarrollo del lado cliente y servidor, pero también para construir, testear, maquetar, y más.
Por qué elegí JavaScript
Soy desarrollador web desde 1998. Por esas épocas usabamos Perl para la mayoría de nuestro desarrollo del lado del servidor, y aún desde esos tiempos teníamos JavaScript del lado del cliente. Las tecnologías web del lado servidor han cambiado inmensamente desde entonces: fuimos a través de oleada tras oleada de distintas tecnologías y lenguajes cómo PHP, ASP, JSP, .NET, Ruby, Python, solo por nombrar algunas. Los desarrolladores comenzaron a darse cuenta que usando dos distintos lenguajes para ambientes cliente y servidor estaba complicando las cosas. Los intentos iniciales para unificar bajo un mismo lenguaje intentaban crear componentes cliente del lado del servidor y compilarlos en JavaScript. Esto no funcionaba como se esperaba y muchos de esos proyectos fallaron (por ejemplo, ASP MVC reemplazando los formularios web de ASP.NET, y podría decirse que GWT será reemplazado por Polymer). en un futuro cercano). Pero era una excelente idea, en esencia: un lenguaje único en el cliente y el servidor, permitiéndonos reusar componentes y recursos (esta es la clave: recursos).
La respuesta era simple: usar JavaScript en el servidor.
De hecho, JavaScript nació con JavaScript Server Side en Netscape Enterprise Server, pero el lenguaje simplemente no estaba listo en esa época. Luego de años de prueba y error, Node.js finalmente emergió, lo cual no solo puso a JavaScript en el servidor, pero además promovió la idea de programación no-bloqueante, cambiando la forma en la que escribimos “fread”(I/O) para siempre (lee más aquí.
En una oración: la programación no-bloqueante apunta a poner tareas que consumen tiempo a un lado, usualmente especificando que se debería hacer una vez que estas tareas se hayan completado, y permitiendo que el procesador maneje otros pedidos mientras tanto.
Pero esas ideas no eran nuevas—entonces, ¿por que se volvieron tan populares con Node.js? Simple, la programación no-bloqueante puede ser alcanzada de distintas formas. Tal vez la más fácil es usar callbacks y un evento en bucle. En la mayoría de los lenguajes, esa no es una tarea fácil: mientras que los ‘callbacks’ son una característica común en algunos lenguajes, un evento en bucle no lo es y usualmente te encuentras aferrándote a librerías externas (por ejemplo: Python, con Tornado). Pero en JavaScript, los callbacks son construidos dentro del lenguaje, como también el evento en bucle, y casi cualquier programador que haya incursionado en JavaScript está familiarizado con ellos (o al menos los han usado, aunque no entiendan del todo que significa un evento en bucle). De repente, cada una de las startup en el Planeta Tierra podía reusar desarrolladores (por ej., recursos) tanto en el lado cliente cómo en el lado del servidor, resolviendo el problema de “Se necesita Gurú Python”.
De repente, cada una de las startup en el Planeta Tierra podía reusar desarrolladores (por ej., recursos) tanto en el lado cliente cómo en el lado del servidor, resolviendo el problema de “Se necesita Gurú Python”.
Entonces, ahora tenemos una plataforma increíblemente rápida (gracias a la programación no-bloqueante) con un lenguaje de programación que es increíblemente fácil de usar (gracias a JavaScript). Pero, ¿Es suficiente? ¿Perdurará? Estoy seguro que JavaScript va a tener un importante lugar en el futuro. Déjame decirte por qué:
- Programación FuncionalJavaScript fue el primer lenguaje de programación que llevó el paradigma funcional a las masas (por supuesto, Lisp llegó primero, pero la mayoría de los desarrolladores nunca han construido una aplicación en Lisp lista para ser usada en producción). Lisp y Self, influencias principales de Javascript, están llenos de ideas innovadoras. Esas ideas pueden liberar nuestras mentes para explorar nuevas técnicas, patrones y paradigmas. Y todos ellos llevan a JavaScript. Mira monads, codificación Church, o incluso (para un ejemplo más práctico) la colección de funciones](http://underscorejs.org/#collections), de Underscore.js las cuales pueden salvarte líneas y líneas de código.
- Objetos Dinámicos y herencia PrototipadaLa programación orientada a objetos sin clases (y sin las interminables herencias de clases) permite rápido desarrollo (crear objetos, agregar métodos y usarlos) pero, lo más importante, reduce el tiempo de refactorización durante tareas de mantenimiento dejando que el desarrollador modifique instancias de objetos en vez de clases. Esta velocidad y flexibilidad pavimenta el camino para el desarrollo rápido.
- JavaScript es InternetJavaScript fue diseñado para Internet, ha estado aquí desde el principio, y no va a irse. Todos los intentos por destruirlo han fallado, mira, por ejemplo, la caída de los Applets Java, el reemplazo de VBScript deMicrosoft, TypeScript (que compilaba a JavaScript), y la caída de Flash en manos del mercado móvil y HTML5. Es imposible reemplazar Javascript sin romper millones de páginas web, así que nuestro objetivo a largo plazo debería ser el de mejorarlo. Y no hay nadie mejor para esa tarea que el Technical Committee 39de ECMA.Ok, alternativas a JavaScript nacen todos los días, cómo CoffeeScript, TypeScript, y los los millones de lenguajes que compilan a JavaScript. Esas alternativas pueden ser útiles para etapas de desarrollo (por medio de mapeos de código fuente), pero fallarán al tratar de suplantar JavaScript a largo plazo por dos razones: sus comunidades nunca serán más grandes, y sus mejores funcionalidades serán adoptadas por el script de ECMA (por ej., JavaScript). JavaScript no es como un lenguaje ensamblador: es un lenguaje de programación de alto nivel con código fuente que puedes entender—entonces deberías entenderlo.
Ahora, gracias al proyecto Esprima, puedes crear tus propias herramientas para jugar con el código fuente, modificándolo, cambiando su estilo, agregando comentarios, instrumentando, y todo de tipo de cosas que puedas imaginar al jugar con el Árbol de Sintaxis Abstracta de tu programa como si estuvieses jugando con un Árbol DOM.
JavaScript de extremo a extremo: Node.js y MongoDB
Entonces, esas son las razones para usar JavaScript. Ahora, voy a usar JavaScript como una razón para usar Node.js y MongoDB.
- Node.jsNode.js es una plataforma para construir aplicaciones de red rápidas y escalables—eso es básicamente lo que dice el sitio de Node.js. Pero Node.js es más que eso: es el entorno de ejecución preferido por cualquier aplicación con acceso de E/S en JavaScript. Incluso si no planeas escribir tu aplicación del servidor principal con Node.js, puedes usar herramientas creadas construidas encima de Node.js para mejorar tu proceso de desarrollo. Por ejemplo: Mocha.js para unit testing, Grunt.js para tareas de construcción automatizadas, o incluso Brackets para completar edición de código.Entonces, si vas a escribir aplicaciones de JavaScript para servidor o cliente, deberías familiarizarte con Node.js, porque vas a necesitar usarlo diariamente. Hay algunas interesantes alternativas), pero ninguna de ellas llega siquiera al 10% de la comunidad de Node.js.
- MongoDBMongoDB es una base de datos NoSQL basada en documentos que usan JavaScript como su lenguaje de consultas, permitiendo completar de extremo-a-extremo la plataforma JavaScript. Pero esa no es siquiera la razón principal para elegir esta base de datos.MongoDB es una base de datos sin esquema que permite persistir tus objetos de una manera flexible y por lo tanto adaptarse más rápidamente a los cambios en los requisitos. Además, es altamente escalable ybasado en map-reduce, lo cual lo hace adecuado para aplicaciones con muchos datos. MongoDB es tan flexible que puede ser usado como una base de datos de documentos sin esquema, un almacén de datos relacional (aunque le faltan transacciones),o incluso almacenamiento de clave-valor para respuestas de caché.
Modularización de Servidor con Express.js
Modularización en el lado del servidor nunca es fácil. Pero con Express.js (y Connect.js) vino la idea de‘middleware’(ó software intermedio). En mi opinión, middleware es la mejor forma de definir componentes en el servidor. Si quieres compararlo con un patrón conocido, se acerca bastante a los tubos y filtros.
La idea básica es que tu componente es parte de una tubería. La tubería procesa el pedido (entrada) y genera una respuesta (salida), pero tu componente no es responsable por la respuesta completa. En cambio, solo modifica lo que necesita y luego delega hacia la otra pieza de la tubería. Cuando la última pieza de la tubería termina su proceso, la respuesta se envía al cliente.
Nos referimos a estas ‘piezas de tubería’ como ‘middleware’. Claramente, podemos crear dos tipos demiddleware:
- Intermedios: Esos que procesan el pedido y la respuesta, pero no son del todo responsables por la respuesta en sí, entonces delegan al siguiente middleware.
- Finales: Esos que toman la responsabilidad por completo en la respuesta final. Ellos procesan y modifican el pedido y la respuesta, pero no necesitan delegar al siguiente middleware. En la práctica, se recomienda que delegues a un siguiente middleware, de todas maneras, para permitir flexibilidad en la arquitectura (por ej., agregar más middleware después), aunque ese middleware no exista (en ese caso la respuesta irá directamente al cliente)