Una introducción a JavaScript de pila completa

 

 

 

  • Implemente rápidamente. Implementar inteligentemente
  • Patrones de diseño para interfaces de IA, con Vitaly Friedman

  • Índice
    1. Por qué uso JavaScript
      1. Programación funcional
      2. Objetos dinámicos y herencia prototípica
      3. JavaScript es Internet
    2. JavaScript de un extremo a otro: Node.js y MongoDB
      1. Nodo.js
      2. MongoDB
    3. Componentización del servidor con Express
    4. Aplicaciones de una sola página
    5. MV del lado del cliente* con Backbone.js, Marionette y Twitter Bootstrap
    6. Mejores prácticas: Grunt, Mocha, Chai, RequireJS y CoverJS
      1. Moca y chai
      2. Gruñido
      3. RequerirJS
      4. PortadaJS
    7. Conclusión
      1. Otras lecturas

    Quiere ser eficiente y ágil mediante el uso de tecnologías que le ayudarán a tener éxito a corto y largo plazo. Y esas tecnologías no siempre son fáciles de distinguir. JavaScript de pila completa da en el blanco. Probablemente lo hayas visto por ahí. Con JavaScript, puede crear aplicaciones escalables y mantenibles, unificadas en un solo lenguaje. No hay duda, es una fuerza a tener en cuenta. En este artículo, Alejandro Hernández presentará estos componentes pieza por pieza.

     

    Hoy en día, con cualquier aplicación web que crees, tienes que tomar docenas de decisiones arquitectónicas. Y quiere tomar las correctas: quiere utilizar tecnologías que permitan un desarrollo rápido , iteración constante, máxima eficiencia, velocidad, solidez y más. Quieres ser delgado y ágil. Quiere utilizar tecnologías que le ayuden a tener éxito a corto y largo plazo. Y esas tecnologías no siempre son fáciles de distinguir.

    En mi experiencia, JavaScript de pila completa da en el blanco. Probablemente lo hayas visto por ahí; quizás hayas considerado su utilidad e incluso lo hayas debatido con amigos. ¿Pero lo has probado tú mismo? En esta publicación, le brindaré una descripción general de por qué JavaScript completo podría ser adecuado para usted y cómo hace su magia.

    Para darle una vista previa rápida:

    ( vista grande )

    Presentaré estos componentes pieza por pieza. Pero primero, una breve nota sobre cómo llegamos a donde estamos hoy.

    Por qué uso JavaScript

    Soy desarrollador web desde 1998. En aquel entonces, usábamos Perl para la mayor parte de nuestro desarrollo del lado del servidor; pero incluso desde entonces, tenemos JavaScript en el lado del cliente. Las tecnologías de servidores web han cambiado enormemente desde entonces: pasamos por una oleada tras otra de lenguajes y tecnologías, como PHP, ASP, JSP, .NET, Ruby, Python, solo por nombrar algunos. Los desarrolladores comenzaron a darse cuenta de que utilizar dos lenguajes diferentes para los entornos de cliente y servidor complica las cosas.

    En la era temprana de PHP y ASP, cuando los motores de plantillas eran solo una idea, los desarrolladores incorporaban el código de la aplicación en su HTML . Ver scripts incrustados como este no era raro:

    script ?php if ($login == true){ ? alert("Welcome"); ?php } ?/script

    O, peor aún:

    script var users_deleted = []; ?php $arr_ids = array(1,2,3,4); foreach($arr_ids as $value){ ? users_deleted.push("php"); ?php } ?/script

    Para empezar, estaban los típicos errores y declaraciones confusas entre idiomas, como fory foreach. Además, escribir código como este en el servidor y en el cliente para manejar la misma estructura de datos es incómodo incluso hoy en día (a menos, por supuesto, que tengas un equipo de desarrollo con ingenieros dedicados al front-end e ingenieros para el back-end, pero incluso si pueden compartir información, no podrán colaborar en el código de los demás):

    ?php $arr = array("apples", "bananas", "oranges", "strawberries"), $obj = array(); $i = 10; foreach($arr as $fruit){ $obj[$fruit] = $i; $i += 10; } echo json_encode(obj);?script $.ajax({ url:"/json.php", success: function(data){ var x; for(x in data){ alert("fruit:" + x + " points:" + data[x]); } } });/script

    Los intentos iniciales de unificarlos en un solo lenguaje fueron crear componentes de cliente en el servidor y compilarlos en JavaScript. Esto no funcionó como se esperaba y la mayoría de esos proyectos fracasaron (por ejemplo, ASP MVC reemplazó los formularios web ASP.NET y se podría decir que GWT será reemplazado en un futuro cercano por Polymer ). Pero la idea era genial, en esencia: un único lenguaje en el cliente y en el servidor, que nos permitiera reutilizar componentes y recursos (y esta es la palabra clave: recursos).

     

    La respuesta fue simple: poner JavaScript en el servidor.

    En realidad, JavaScript nació en el lado del servidor en Netscape Enterprise Server, pero el lenguaje simplemente no estaba listo en ese momento. Después de años de prueba y error, finalmente surgió Node.js , que no solo puso JavaScript en el servidor, sino que también promovió la idea de programación sin bloqueo , trayendolo del mundo de nginx, gracias a la experiencia en nginx del creador de Node, y (sabiamente) manteniéndolo simple, gracias a la naturaleza de bucle de eventos de JavaScript.

    (En una oración, la programación sin bloqueo tiene como objetivo dejar de lado las tareas que consumen mucho tiempo, generalmente especificando qué se debe hacer cuando se completan estas tareas y permitiendo que el procesador maneje otras solicitudes mientras tanto).

    Node.js cambió para siempre la forma en que manejamos el acceso de E/S. Como desarrolladores web, estábamos acostumbrados a las siguientes líneas al acceder a bases de datos (E/S):

    var resultset = db.query("SELECT * FROM 'table'");drawTable(resultset);

    Esta línea esencialmente bloquea su código, porque su programa deja de ejecutarse hasta que el controlador de su base de datos tenga que resultsetregresar. Mientras tanto, la infraestructura de su plataforma proporciona los medios para la concurrencia, generalmente mediante subprocesos y bifurcaciones.

    Con Node.js y la programación sin bloqueo, tenemos más control sobre el flujo del programa. Ahora (incluso si todavía tiene la ejecución paralela oculta por el controlador de su base de datos (E/S)), puede definir qué debe hacer el programa mientras tanto y qué hará cuando reciba el resultset:

    db.query("SELECT * FROM 'table'", function(resultset){ drawTable(resultset);});doSomeThingElse();

    Con este fragmento, hemos definido dos flujos de programa: el primero maneja nuestras acciones justo después de enviar la consulta a la base de datos, mientras que el segundo maneja nuestras acciones justo después de recibir nuestra resultSetusando una simple devolución de llamada. Esta es una forma elegante y poderosa de gestionar la concurrencia. Como dicen, "Todo funciona en paralelo, excepto el código". Por lo tanto, su código será fácil de escribir, leer, comprender y mantener, todo sin perder el control sobre el flujo del programa.

    Estas ideas no eran nuevas en ese momento; entonces, ¿por qué se volvieron tan populares con Node.js? Simple: la programación sin bloqueo se puede lograr de varias maneras. Quizás lo más sencillo sea utilizar devoluciones de llamada y un bucle de eventos . En la mayoría de los lenguajes, eso no es una tarea fácil: si bien las devoluciones de llamada son una característica común en algunos otros lenguajes, un bucle de eventos no lo es, y a menudo te encontrarás lidiando con bibliotecas externas (por ejemplo, Python con Tornado ).

     

    Pero en JavaScript, las devoluciones de llamada están integradas en el lenguaje, al igual que el bucle de eventos, y casi todos los programadores que han incursionado en JavaScript están familiarizados con ellas (o al menos las han usado, incluso si no entienden muy bien cuál es el evento). el bucle es ). De repente, cada startup en la Tierra podría reutilizar desarrolladores (es decir, recursos) tanto en el lado del cliente como en el del servidor, resolviendo el problema de publicación de empleo "Se necesita Python Guru" .

    Entonces, ahora tenemos una plataforma increíblemente rápida (gracias a la programación sin bloqueo), con un lenguaje de programación increíblemente fácil de usar (gracias a JavaScript). ¿Pero es suficiente? ¿Durará? Estoy seguro de que JavaScript tendrá un lugar importante en el futuro. Déjame decirte por qué.

    Programación funcional

    JavaScript fue el primer lenguaje de programación que llevó el paradigma funcional a las masas (por supuesto, Lisp fue el primero, pero la mayoría de los programadores nunca han creado una aplicación lista para producción usándolo). Lisp y Self, las principales influencias de Javascript , están llenos de ideas innovadoras que pueden liberar nuestra mente para explorar nuevas técnicas, patrones y paradigmas. Y todos ellos se trasladan a JavaScript. Eche un vistazo a las mónadas , los números de iglesia o incluso (para un ejemplo más práctico) las funciones de colecciones de Underscore , que pueden ahorrarle líneas y líneas de código.

    Objetos dinámicos y herencia prototípica

    La programación orientada a objetos sin clases (y sin infinitas jerarquías de clases) permite un desarrollo rápido: simplemente cree objetos, agregue métodos y utilícelos. Más importante aún, reduce el tiempo de refactorización durante las tareas de mantenimiento al permitir al programador modificar instancias de objetos, en lugar de clases. Esta velocidad y flexibilidad allanan el camino para un rápido desarrollo.

    JavaScript es Internet

    JavaScript fue diseñado para Internet . Ha estado aquí desde el principio y no va a desaparecer . Todos los intentos de destruirlo han fracasado; Recordemos, por ejemplo, la caída de los Applets de Java , el reemplazo de VBScript por TypeScript de Microsoft (que se compila en JavaScript) y la desaparición de Flash a manos del mercado móvil y HTML5. Reemplazar JavaScript sin dañar millones de páginas web es imposible , por lo que nuestro objetivo en el futuro debería ser mejorarlo. Y nadie es más adecuado para el trabajo que el Comité Técnico 39 de la ECMA.

    Claro, cada día nacen alternativas a JavaScript, como CoffeeScript , TypeScript y los millones de lenguajes que se compilan en JavaScript . Estas alternativas pueden ser útiles para las etapas de desarrollo ( a través de mapas fuente ), pero no lograrán suplantar a JavaScript a largo plazo por dos razones: sus comunidades nunca serán más grandes y sus mejores características serán adoptadas por ECMAScript (es decir, JavaScript). JavaScript no es un lenguaje ensamblador: es un lenguaje de programación de alto nivel con código fuente que puedes entender, por lo que debes entenderlo .

     

    JavaScript de un extremo a otro: Node.js y MongoDB

    Hemos cubierto las razones para usar JavaScript. A continuación, veremos JavaScript como una razón para usar Node.js y MongoDB.

    Nodo.js

    Node.js es una plataforma para crear aplicaciones de red rápidas y escalables; eso es más o menos lo que dice el sitio web de Node.js. Pero Node.js es más que eso: es el entorno de ejecución de JavaScript más popular que existe en este momento, utilizado por un montón de aplicaciones y bibliotecas; incluso las bibliotecas del navegador ahora se ejecutan en Node.js. Más importante aún, esta rápida ejecución del lado del servidor permite a los desarrolladores centrarse en problemas más complejos, como Natural para el procesamiento del lenguaje natural . Incluso si no planea escribir su aplicación de servidor principal con Node.js, puede usar herramientas creadas sobre Node.js para mejorar su proceso de desarrollo; por ejemplo, Bower para gestión de paquetes front-end, Mocha para pruebas unitarias, Grunt para tareas de compilación automatizadas e incluso Brackets para edición de código de texto completo. Onlyfans gratis de chicas y chicos

    Entonces, si vas a escribir aplicaciones JavaScript para el servidor o el cliente, debes familiarizarte con Node.js, porque lo necesitarás a diario. Existen algunas alternativas interesantes , pero ninguna tiene ni siquiera el 10% de la comunidad de Node.js.

    MongoDB

    MongoDB es una base de datos basada en documentos NoSQL que utiliza JavaScript como lenguaje de consulta (pero no está escrita en JavaScript), completando así nuestra plataforma JavaScript de extremo a extremo. Pero esa ni siquiera es la razón principal para elegir esta base de datos.

    MongoDB no tiene esquema , lo que le permite conservar objetos de forma flexible y, por tanto, adaptarse rápidamente a los cambios en los requisitos. Además, es altamente escalable y se basa en map-reduce , lo que lo hace adecuado para aplicaciones de big data. MongoDB es tan flexible que puede usarse como una base de datos de documentos sin esquema, un almacén de datos relacional (aunque carece de transacciones , que solo se pueden emular ) e incluso como un almacén clave-valor para almacenar en caché respuestas, como Memcached y Redis .

    Componentización del servidor con Express

    La componenteización del lado del servidor nunca es fácil. Pero con Express (y Connect ) surgió la idea del "middleware". En mi opinión, el middleware es la mejor manera de definir componentes en el servidor. Si desea compararlo con un patrón conocido, se parece bastante a tuberías y filtros.

    La idea básica es que su componente sea parte de una tubería. La canalización procesa una solicitud (es decir, la entrada) y genera una respuesta (es decir, la salida), pero su componente no es responsable de la respuesta completa. En cambio, modifica sólo lo que necesita y luego delega en la siguiente pieza del proceso. Cuando la última parte del proceso termina de procesarse, la respuesta se envía de vuelta al cliente.

    Nos referimos a estas partes del proceso como middleware. Claramente, podemos crear dos tipos de middleware:

    • Intermedios . Un intermediario procesa la solicitud y la respuesta, pero no es totalmente responsable de la respuesta en sí y, por lo tanto, delega en el siguiente middleware.
    • Finales . Un final tiene plena responsabilidad sobre la respuesta final. Procesa y modifica la solicitud y la respuesta, pero no necesita delegar al siguiente middleware. En la práctica, delegar al siguiente middleware de todos modos permitirá flexibilidad arquitectónica (es decir, agregar más middleware más adelante), incluso si ese middleware no existe (en cuyo caso, la respuesta iría directamente al cliente).

    ( vista grande )

     

    Como ejemplo concreto, considere un componente de "administrador de usuarios" en el servidor . En términos de middleware, tendríamos tanto finales como intermedios. Para nuestras finales, tendríamos funciones como crear un usuario y enumerar usuarios. Pero antes de que podamos realizar esas acciones, necesitamos nuestros intermediarios para la autenticación (porque no queremos que entren solicitudes no autenticadas y creen usuarios). Una vez que hayamos creado estos intermediarios de autenticación, podemos simplemente conectarlos en cualquier lugar donde queramos convertir una característica no autenticada previamente en una característica autenticada.

    Aplicaciones de una sola página

    Cuando trabaja con JavaScript de pila completa, a menudo se concentrará en crear aplicaciones de una sola página (SPA). La mayoría de los desarrolladores web se sienten tentados más de una vez a probar suerte en los SPA. He creado varias (en su mayoría propietarias) y creo que son simplemente el futuro de las aplicaciones web . ¿Alguna vez ha comparado un SPA con una aplicación web normal en una conexión móvil? La diferencia en la capacidad de respuesta es del orden de decenas de segundos.

    (Nota: Es posible que otros no estén de acuerdo conmigo. Twitter, por ejemplo, revirtió su enfoque SPA . Mientras tanto, grandes sitios web como Zendesk están avanzando hacia él. He visto suficiente evidencia de los beneficios de los SPA para creer en ellos, pero las experiencias variar.)

    Si los SPA son tan buenos, ¿por qué crear su producto de forma heredada? Un argumento común que escucho es que la gente está preocupada por el SEO. Pero si maneja las cosas correctamente, esto no debería ser un problema: puede adoptar diferentes enfoques, desde usar un navegador sin cabeza (como PhantomJS ) para representar el HTML cuando se detecta un rastreador web hasta realizar la representación del lado del servidor con la ayuda. de los marcos existentes.

    MV del lado del cliente* con Backbone.js, Marionette y Twitter Bootstrap

    Se ha hablado mucho de los frameworks MV* para SPA . Es una elección difícil, pero yo diría que los tres primeros son Backbone.js , Ember y AngularJS .

    Los tres están muy bien considerados. ¿ Pero cuál es mejor para ti ?

    Lamentablemente, debo admitir que tengo una experiencia limitada con AngularJS, así que lo dejaré fuera de la discusión. Ahora, Ember y Backbone.js representan dos formas diferentes de atacar el mismo problema.

    Backbone.js es mínimo y ofrece lo suficiente para crear un SPA simple. Ember, por otro lado, es un marco completo y profesional para la creación de SPA. Tiene más detalles, pero también una curva de aprendizaje más pronunciada. (Puedes leer más sobre Ember.js aquí ).

     

    Dependiendo del tamaño de su aplicación, la decisión podría ser tan fácil como mirar la proporción "funciones utilizadas" y "funciones disponibles" , lo que le dará una gran pista.

    El estilo también es un desafío, pero nuevamente, podemos contar con marcos que nos rescaten. Para CSS, Twitter Bootstrap es una buena opción porque ofrece un conjunto completo de estilos que están listos para usar de inmediato y son fáciles de personalizar .

    Bootstrap se creó en el lenguaje LESS y es de código abierto, por lo que podemos modificarlo si es necesario. Viene con un montón de controles UX que están bien documentados . Además, un modelo de personalización te permite crear el tuyo propio. Definitivamente es la herramienta adecuada para el trabajo.

    Mejores prácticas: Grunt, Mocha, Chai, RequireJS y CoverJS

    Finalmente, debemos definir algunas mejores prácticas, así como mencionar cómo implementarlas y mantenerlas. Normalmente, mi solución se centra en varias herramientas, que a su vez están basadas en Node.js.

    Moca y chai

    Estas herramientas le permiten mejorar su proceso de desarrollo aplicando desarrollo basado en pruebas (TDD) o desarrollo basado en comportamiento (BDD), creando la infraestructura para organizar sus pruebas unitarias y un ejecutor para ejecutarlas automáticamente.

    Existen muchos marcos de pruebas unitarias para JavaScript. ¿Por qué utilizar moca? La respuesta corta es que es flexible y completo.

    La respuesta larga es que tiene dos características importantes (interfaces y reporteros) y una ausencia significativa (afirmaciones). Permítame explicarle:

    • Interfaces . Tal vez esté acostumbrado a los conceptos TDD de suites y pruebas unitarias, o tal vez prefiera ideas BDD de especificaciones de comportamiento con describey should. Mocha te permite utilizar ambos enfoques.
    • Reporteros . La ejecución de su prueba generará informes de los resultados y podrá formatear estos resultados utilizando varios reporteros. Por ejemplo, si necesita alimentar un servidor de integración continua, encontrará un reportero que lo haga.
    • Falta de una biblioteca de afirmaciones . Lejos de ser un problema, Mocha fue diseñado para permitirle usar la biblioteca de aserciones de su elección, brindándole aún más flexibilidad. Tienes muchas opciones y aquí es donde entra en juego Chai.

    Chai es una biblioteca de aserciones flexible que le permite utilizar cualquiera de los tres estilos de aserciones principales:

    • assertEste es el estilo de afirmación clásico del TDD de la vieja escuela. Por ejemplo:assert.equal(variable, "value");
    • expectEste estilo de afirmación encadenable se usa más comúnmente en BDD. Por ejemplo:expect(variable).to.equal("value");
    • shouldEsto también se usa en BDD, pero lo prefiero expectporque shoulda menudo suena repetitivo (es decir, con la especificación de comportamiento de "(debería hacer algo...)"). Por ejemplo:variable.should.equal("value");

    Chai combina perfectamente con Mocha. Usando solo estas dos bibliotecas, puedes escribir tus pruebas en TDD, BDD o cualquier estilo imaginable.

     

    Gruñido

    Grunt le permite automatizar tareas de compilación, cualquier cosa, incluido copiar y pegar simple y concatenación de archivos, precompilación de plantillas, compilación de lenguajes de estilo (es decir, SASS y LESS), pruebas unitarias (con Mocha), linting y minificación de código (por ejemplo, con UglifyJS o compilador de cierre ). Puedes agregar tu propia tarea automatizada a Grunt o buscar en el registro , donde hay cientos de complementos disponibles (una vez más, usar una herramienta con una gran comunidad detrás vale la pena). Grunt también puede monitorear sus archivos y activar acciones cuando se modifica alguno.

    RequerirJS

    RequireJS puede parecer una forma más de cargar módulos con la API de AMD , pero os aseguro que es mucho más que eso. Con RequireJS, puede definir dependencias y jerarquías en sus módulos y dejar que la biblioteca RequireJS las cargue por usted. También proporciona una manera fácil de evitar la contaminación global del espacio variable al definir todos los módulos dentro de las funciones. Esto hace que los módulos sean reutilizables, a diferencia de los módulos con espacios de nombres . Piénselo: si define un módulo como Demoapp.helloWordModuley desea portarlo a Firstapp.helloWorldModule, entonces necesitará cambiar cada referencia al Demoappespacio de nombres para hacerlo portátil.

    RequireJS también le ayudará a adoptar el patrón de inyección de dependencia . Suponga que tiene un componente que necesita una instancia del objeto de la aplicación principal (un singleton). Al usar RequireJS, te das cuenta de que no debes usar una variable global para almacenarla y que no puedes tener una instancia como dependencia de RequireJS. Entonces, en lugar de eso, necesitas requerir esta dependencia en el constructor de tu módulo. Veamos un ejemplo.

    En main.js:

     define( ["App","module"], function(App, Module){ var app = new App(); var module = new Module({ app: app }) return app; } );

    En module.js:

     define([], function(){ var module = function(options){ this.app = options.app; }; module.prototype.useApp = function(){ this.app.performAction(); }; return module } );

    Tenga en cuenta que no podemos definir el módulo con una dependencia main.jssin crear una referencia circular.

    PortadaJS

    La cobertura del código es una métrica para evaluar sus pruebas. Como su nombre lo indica, le indica qué parte de su código está cubierto por su conjunto de pruebas actual. CoverJS mide la cobertura del código de sus pruebas instrumentando declaraciones (en lugar de líneas de código, como JSCoverage ) en su código y generando una versión instrumentada del código. También puede generar informes para alimentar su servidor de integración continua .

    Conclusión

    JavaScript de pila completa no es la respuesta a todos los problemas. Pero su comunidad y su tecnología le llevarán muy lejos. Con JavaScript, puede crear aplicaciones escalables y mantenibles, unificadas en un solo lenguaje. No hay duda, es una fuerza a tener en cuenta.

    Otras lecturas

    • Una introducción completa a Backbone.Marionette (Parte 1)
    • Viaje a través de la jungla MVC de JavaScript
    • Una introducción detallada a Webpack
    • Ponte en marcha con Grunt

    (al, ea, mrn)Explora más en

    • Codificación
    • Herramientas
    • javascript
    • Técnicas





    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Una introducción a JavaScript de pila completa

    Una introducción a JavaScript de pila completa

    Implemente rápidamente. Implementar inteligentemente Patrones de diseño para interfaces de IA, con Vitaly Friedman Índice

    programar

    es

    https://aprendeprogramando.es/static/images/programar-una-introduccion-a-javascript-de-pila-completa-834-0.jpg

    2024-05-20

     

    Una introducción a JavaScript de pila completa
    Una introducción a JavaScript de pila completa

    Si crees que alguno de los contenidos (texto, imagenes o multimedia) en esta página infringe tus derechos relativos a propiedad intelectual, marcas registradas o cualquier otro de tus derechos, por favor ponte en contacto con nosotros en el mail [email protected] y retiraremos este contenido inmediatamente

     

     

    Top 20