👨🏼‍💻

khriztianmoreno's Blog

Inicio Etiquetas Acerca |

Posts with tag javascript

Node.js Corepack: Control de versiones para gestores de paquetes

2024-12-10
javascriptnodejstutorial

El problema con los gestores de paquetes tradicionalesDurante años, npm ha sido el gestor de paquetes de facto para Node.js. Aunque ofrece características robustas como acceso privado a paquetes y autenticación de dos factores, también tiene algunos inconvenientes:Velocidades de instalación lentas: npm puede ser notoriamente lento, especialmente para proyectos grandes.Directorios node_modules abultados: Estos directorios pueden consumir mucho espacio en disco.Configuración compleja: la configuración de npm puede ser intrincada y difícil de dominar.Para solucionar estos problemas, han surgido gestores de paquetes alternativos como Yarn y pnpm. Yarn es conocido por su velocidad, mientras que pnpm optimiza el espacio en disco compartiendo dependencias.¿Qué es Corepack?Corepack es una nueva característica experimental en Node.js que te permite gestionar las versiones de los gestores de paquetes en tus máquinas y entornos. Esto significa que todos los miembros del equipo utilizarán la misma versión del gestor de paquetes, lo que puede ayudar a evitar problemas de compatibilidad.{ "name": "my-project", "scripts": { "start": "node index.js" }, "packageManager": "pnpm@8.5.1" // what is this? (Corepack) }Primeros pasos con CorepackPara activar Corepack, puede ejecutar el siguiente comando:corepack enableUna vez habilitado Corepack, para configurar el gestor de paquetes de tu proyecto, ejecuta corepack use. Este comando actualiza tu package.json automáticamente.corepack use pnpm@8.x # sets the latest 8.x pnpm version in the package.json corepack use yarn@* # sets the latest Yarn version in the package.json¿Por qué usar Corepack?Corepack puede ayudarte a evitar problemas de compatibilidad asegurando que todos los miembros del equipo utilizen la misma versión del gestor de paquetes. También puede ayudarnos a gestionar las versiones del gestor de paquetes en diferentes entornos, como desarrollo, producción y pruebas.El futuro de CorepackCorepack representa un importante paso adelante en la gestión de paquetes Node.js. Al proporcionar una interfaz unificada para diferentes gestores de paquetes, simplifica el flujo de trabajo de desarrollo y reduce la complejidad asociada a la gestión de dependencias. A medida que Corepack madura, tiene el potencial de convertirse en la forma estándar de gestionar paquetes Node.js.ReferenciasCorepack DocumentationCorepack : Managing the Package ManagersHow To Use Corepack¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

Patrones de obtención de datos en React

2024-12-09
reactjavascriptweb-development

Imagina construir una página web que muestre datos meteorológicos en tiempo real o una lista de productos de una tienda en línea. ¿Cómo obtiene esta información tu aplicación React? La respuesta está en la obtención de datos. Este proceso implica recuperar datos de varias fuentes (como APIs, bases de datos) e incorporarlos en tus componentes de React.Obtención de Datos Secuencial:Piensa en la obtención de datos secuencial como un proceso paso a paso. Obtienes una pieza de datos, esperas a que llegue y luego pasas a la siguiente.Ejemplo: Obtener información del usuario, luego sus pedidos y finalmente su dirección.// Sequential fetching using async/await async function fetchData() { const user = await fetchUser(); const orders = await fetchOrders(user.id); const address = await fetchAddress(user.id); // ... }Obtención de Datos en Paralelo:En la obtención de datos en paralelo, se realizan múltiples solicitudes de datos simultáneamente.Ejemplo: Obtener información del usuario, pedidos y dirección al mismo tiempo.// Parallel fetching using Promise.all Promise.all([fetchUser(), fetchOrders(userId), fetchAddress(userId)]) .then(([user, orders, address]) => { // ... }) .catch((error) => { // ... });Prefetching de Datos:Para mejorar la velocidad percibida de tu aplicación, considera prefetching de datos antes de que sean necesarios. Esta técnica es particularmente efectiva para datos que probablemente se necesitarán pronto pero no de inmediato. Por ejemplo, al utilizar un framework como Next.js construido sobre React, puedes hacer prefetch la página siguiente y sus datos asociados usando su componente Link.Ejemplo:<Link href="/posts/1" prefetch> <a>Post 1</a> </Link>Tan pronto como este componente Link se vuelve visible en la pantalla, los datos para la "Página Siguiente" se precargan. Estas optimizaciones sutiles pueden mejorar significativamente el rendimiento percibido de tu aplicación, haciéndola sentir más receptiva.Conclusión:Elegir el patrón de obtención de datos adecuado depende de tu caso de uso específico.Secuencial: Simple de implementar, adecuado para aplicaciones de pequeña escala.Paralelo: Mejora el rendimiento para conjuntos de datos más grandes, pero puede ser más complejo.Prefetching: Mejora la experiencia del usuario al reducir los tiempos de carga percibidos.Puntos Clave:Async/await: Una forma moderna de manejar operaciones asíncronas en JavaScript.Promesas: Una forma de representar la eventual finalización (o falla) de una operación asíncrona.Rendimiento: La obtención de datos en paralelo y el prefetching pueden mejorar significativamente el rendimiento.Experiencia del usuario: El prefetching puede hacer que tu aplicación se sienta más rápida.Consejos Adicionales:Manejo de errores: Siempre maneja los errores de manera elegante para proporcionar una mejor experiencia de usuario.Caché: Almacena datos accedidos frecuentemente para reducir el número de solicitudes de red.Gestión de estado: Usa bibliotecas como Redux o Zustand para gestionar el estado complejo de la aplicación, especialmente cuando se trata de datos obtenidos.Al entender estos patrones, puedes construir aplicaciones React más eficientes y receptivas.¿Te gustaría que elaborara alguno de estos conceptos o proporcionara más ejemplos de código?Profile@khriztianmoren

WebContainers al máximo - Bolt.new combina IA y desarrollo full-stack en el navegador

2024-10-08
javascriptaiweb-development

¿Recuerdas los WebContainers? Es el "microsistema operativo" basado en WebAssembly que puede ejecutar las operaciones de Vite y todo el ecosistema Node.js en el navegador. El equipo de StackBlitz creó WebContainers para potenciar su IDE en el navegador, pero a menudo parecía que la tecnología todavía estaba buscando un caso de uso decisivo, hasta ahora.Esto se debe a que StackBlitz acaba de lanzar bolt.new , un sandbox de desarrollo impulsado por IA que Eric Simons describió durante ViteConf como "como si Claude o ChatGPT hubieran tenido un bebé con StackBlitz".Bolt.newIntentaré no imaginarlo demasiado vívidamente, pero en base a las críticas abrumadoramente positivas hasta el momento, supongo que está funcionando: docenas de desarrolladores lo describen como una combinación de v0, Claude, Cursor y Replit.En qué se diferencia Bolt: las herramientas de código de IA existentes a menudo pueden ejecutar algo de JavaScript/HTML/CSS básico en el navegador, pero para proyectos más complejos, es necesario copiar y pegar el código en un entorno local.Pero Bolt no. Al utilizar WebContainers, puede solicitar, ejecutar, editar e implementar aplicaciones web completas , todo desde el navegador.Así es como se ve:Puedes solicitarle a bolt.new que cree una aplicación de varias páginas lista para producción con un backend y una base de datos específicos, usando cualquier stack tecnológico que desees (por ejemplo: “Construye un blog personal usando Astro, Tailwind y shadcn”).A diferencia de otras herramientas, Bolt puede instalar y ejecutar paquetes y bibliotecas npm relevantes, interactuar con API de terceros y ejecutar servidores Node.Puede editar manualmente el código que genera a través de un editor en el navegador o hacer que Bolt resuelva los errores por usted . Esto es exclusivo de Bolt, porque integra IA en todos los niveles de WebContainers (no solo en el paso CodeGen).Puedes implementar en producción desde el chat a través de Netlify, sin necesidad de iniciar sesión.Hay mucho más que podríamos analizar aquí, pero la demostración de Eric es bastante salvaje.Para cerrar: desde fuera, no siempre estuvo claro si StackBlitz alguna vez obtendría un retorno significativo de la inversión durante los más de 5 años que han pasado desarrollando WebContainers. Pero, de repente, parece que podrían estar en una posición única para ayudar a los desarrolladores a aprovechar la IA para crear aplicaciones legítimas FullStack.<iframe width="560" height="315" src="https://www.youtube.com/embed/knLe8zzwNRA?si=7R7-1HxzwuyzL0EZ&amp;start=700" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

¡Rust está revolucionando el desarrollo JavaScript!

2024-07-24
web-developmentjavascript

Rspack acaba de lanzar su versión 1.0 y el sueño de usar herramientas de compilación basadas en Rust para acelerar el ecosistema JavaScript está más vivo que nunca.¿Cómo llegamos hasta aquí? A principios del año pasado, un equipo de desarrolladores en ByteDance enfrentaba problemas de rendimiento al mantener las "muchas aplicaciones monolíticas grandes" de la compañía. Así que hicieron lo que cualquier buen desarrollador haría: culparon a webpack.Pero no se detuvieron ahí. En marzo de 2023, lanzaron Rspack v0.1, un bundler JavaScript de alto rendimiento escrito en Rust y diseñado para ser completamente compatible con el ecosistema de webpack.RspackAvancemos hasta hoy, y Rspack ahora tiene 100k descargas semanales y ha introducido mejoras clave que lo preparan para producción:Mejor rendimiento: Nuevas características como la compilación perezosa y otras optimizaciones de rendimiento hacen que los tiempos de compilación de Rspack 1.0 sean más de 20 veces más rápidos que webpack 5.Mayor compatibilidad con webpack: Más del 80% de los 50 plugins de webpack más descargados ahora se pueden usar en Rspack, acercándolo a convertirse en un verdadero reemplazo directo para webpack.Menor complejidad: Crearon una nueva cadena de herramientas llamada Rstack que incluye proyectos separados como Rsbuild, Rspress y Rslib, cada uno dirigido a diferentes casos de uso. Esto reduce la complejidad de configurar una herramienta todo en uno como Rspack (o webpack), sin dejar de mantener la flexibilidad.En resumen: Rspack ofrece una propuesta de valor bastante simple para los desarrolladores: si ya usas webpack, te facilitará mucho migrar a su bundler que es más rápido, más fácil de usar y aún totalmente compatible con la API de webpack. El tiempo dirá si eso será suficiente para convencer a las masas a probarlo

Desbloquea tu creatividad con Google Gemini y JavaScript - Guía práctica

2024-06-12
javascriptaitutorial

Hola! Hoy les traigo una nueva herramienta que potenciará tu creatividad a otro nivel: Google Gemini. Esta API de inteligencia artificial te permite generar texto de alta calidad en español, desde simples frases hasta historias completas, con solo unas pocas líneas de código.¿Qué es Google Gemini?Google Gemini es un modelo de lenguaje de última generación desarrollado por Google AI. Se ha entrenado con un conjunto de datos masivo de texto y código, lo que le permite comprender y generar lenguaje natural con una precisión impresionante.¿Qué podemos hacer con Google Gemini y JavaScript?Las posibilidades son infinitas. Aquí te presento algunos ejemplos:Generar contenido creativo: Escribe poemas, historias, guiones, artículos de blog, o cualquier tipo de contenido textual que puedas imaginar.Traducir idiomas: Traduce textos de un idioma a otro de forma rápida y precisa. Responder preguntas: Obtén respuestas a tus preguntas de forma informativa y completa.Crear chatbots: Desarrolla chatbots conversacionales que interactúen con los usuarios de forma natural.Automatizar tareas: Automatiza la generación de informes, correos electrónicos, y otras tareas que requieren procesamiento de lenguaje natural.¿Cómo empezar?Para empezar a usar Google Gemini con JavaScript, solo necesitas:Una cuenta de Google Cloud Platform: https://cloud.google.com/Habilitar la API de Google Gemini: https://ai.google.dev/Ejemplo práctico:En este ejemplo, vamos a generar un poema usando Google Gemini y JavaScript.const { GoogleGenerativeAI } = require("@google/generative-ai"); // Access your API key as an environment variable (see "Set up your API key" above) const genAI = new GoogleGenerativeAI(process.env.API_KEY); async function run() { // For embeddings, use the embedding-001 model const model = genAI.getGenerativeModel({ model: "embedding-001" }); const text = "Escribe un poema sobre la naturaleza"; const result = await model.embedContent(text); const embedding = result.embedding; console.log(embedding.values); } run();Para la generación de texto usamos el método getGenerativeModel del objeto genAI.Ejemplo de poema generado:La tierra verde, el cielo azul, el sol brilla con luz de cristal. Las flores florecen en el jardín, los pájaros cantan con dulce trino. El viento susurra entre las hojas, las abejas zumban entre las flores. La naturaleza es un regalo divino, un lugar de paz y armonía.Conclusión:Google Gemini y JavaScript son una combinación poderosa que te permite desbloquear tu creatividad y desarrollar aplicaciones increíbles. Con esta guía práctica, ya estás listo para empezar a explorar las posibilidades infinitas de esta tecnología.Recursos adicionales:Documentación de Google Gemini: https://ai.google.dev/docsTutoriales de Google Gemini: https://m.youtube.com/watch?v=TXvbT8ORI50Ejemplos de código de Google Gemini: https://m.youtube.com/watch?v=jTdouaDuUOA¡Anímate a experimentar con Google Gemini y JavaScript! Comparte tus creaciones en los comentarios y déjame saber qué te parece esta herramienta.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

Cómo mockear una solicitud HTTP con Jest 💻

2024-05-07
javascripttestingnodejsjestweb-development

Hoy quería mostrarles cómo escribir correctamente una prueba.Pero cualquiera puede encontrar cómo ejecutar una prueba sencilla. Y aquí, buscamos ayudarle a encontrar respuestas que no encontrará en ningún otro lugar.Entonces pensé que llevaríamos las cosas un paso más allá.Ejecutemos una prueba más compleja, en la que tendrás que simular 1 o 2 partes de la función que estás probando.[En caso de que seas nuevo aquí: mock es como usar un doble en una película. Es una forma de reemplazar una parte complicada de tu código (como llamar a una API) con algo más simple que pretende ser real, para que pueda probar el resto de tu código fácilmente].MI testing framework elegido es Jest, porque hace que todo sea mucho más fácil:Configuración cero: una de las principales ventajas de Jest es su configuración sin configuración. Está diseñado para funcionar desde el primer momento con una configuración mínima, lo que lo hace muy atractivo para proyectos que desean implementar pruebas de manera rápida y eficiente.Prueba de instantáneas: Jest introdujo el concepto de Snapshot Testing, que es particularmente útil para probar componentes de la interfaz de usuario. Toma una instantánea de la salida renderizada de un componente y garantiza que no cambie inesperadamente en pruebas futuras.Mocking y Spies Integrados: Jest viene con soporte integrado para funciones, módulos y temporizadores simulados, lo que facilita la prueba de componentes o funciones de forma aislada sin preocuparse por sus dependencias.Compatibilidad con pruebas asincrónicas: Jest admite pruebas asincrónicas listas para usar, lo cual es esencial para las pruebas en aplicaciones JavaScript modernas que a menudo dependen de operaciones asincrónicas como llamadas API o consultas de bases de datos.Image descriptionDe todos modos, entremos en las pruebas:Paso 1: configurar tu proyectoCree un nuevo directorio de proyecto y navegue hasta élInicialice un nuevo proyecto npm: npm init -yInstale Jest: npm install --save-dev jestInstale axios para realizar solicitudes HTTP: npm install axiosEstos son los requisitos básicos. Nada nuevo o sofisticado aquí. Vamonos.Paso 2: escribir una función con una llamada APIAhora, digamos que inicia sesión en algún tipo de aplicación. StackOverflow, por ejemplo. Lo más probable es que en la parte superior derecha veas información sobre tu perfil. Tal vez su nombre completo y nombre de usuario, por ejemplo.Para obtenerlos, normalmente tenemos que realizar una llamada a la API para obtenerlos. Entonces, veamos cómo haríamos eso.Cree un archivo llamado user.jsDentro de user.js, escriba una función que realice una llamada API. Por ejemplo, usar axios para recuperar datos del usuario:// user.js import axios from "axios"; export const getUser = async (userId) => { const response = await axios.get(`https://api.example.com/users/${userId}`); return response.data; };Paso 3: crear el archivo de pruebaBien, ahora que tenemos una función que nos trae el usuario según la identificación que solicitamos, veamos cómo podemos probarla.Recuerde, queremos algo que funcione siempre y para todos los desarrolladores.Lo que significa que no queremos depender de si el servidor se está ejecutando o no (ya que esto no es lo que estamos probando).Y no queremos depender de los usuarios que tenemos en la base de datos.Porque en mi base de datos, el ID1 podría pertenecer a mi usuario administrador, mientras que en su base de datos, el ID1 podría pertenecer a SU usuario administrador.Esto significa que la misma función nos daría resultados diferentes. Lo que haría que la prueba fallara, aunque la función funcione correctamente.Siga leyendo para ver cómo abordamos este problema mediante los mocks.Cree un archivo llamado user.test.js en el mismo directorio.Dentro de este archivo, importe la función que desea probar:import axios from "axios"; jest.mock("axios"); import { getUser } from "./user";Escriba su caso de prueba, simule la llamada y recupere datos simulados.test("should fetch user data", async () => { // Mock data to be returned by the Axios request const mockUserData = { id: "1", name: "John Doe" }; axios.get.mockResolvedValue({ data: mockUserData }); // Call the function const result = await getUser("1"); // Assert that the Axios get method was called correctly expect(axios.get).toHaveBeenCalledWith("https://api.example.com/users/1"); // Assert that the function returned the correct data expect(result).toEqual(mockUserData); });Paso 4: ejecutar la pruebaAgregue un script de prueba a su package.json:"scripts": { "test": "jest" }Ejecute sus pruebas con npm test.Paso 5: revise los resultadosJest mostrará el resultado de su prueba en la terminal. La prueba debería pasar, lo que indica que getUser está devolviendo los datos simulados como se esperaba.Felicitaciones, ahora tienes una prueba funcional con Jest y Mocking.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoren

¿Estás cometiendo ESTOS errores de pruebas y mocking unitarios?

2024-04-08
javascripttestingweb-development

Las pruebas son difíciles.Y no importa si eres un tester experimentado o principiante...Si ha realizado un esfuerzo significativo para probar una aplicación...Es probable que hayas cometido algunos de estos errores de prueba y mocking en el pasado.Desde casos de prueba repletos de código duplicado y enormes hooks de ciclo de vida, hasta casos de mocking convenientemente incorrectos y casos extremos que faltan y furtivos, hay muchos culpables comunes.He seguido algunos de los casos más populares y los enumero a continuación. Continúe y cuente cuántos de ellos ha hecho en el pasado.Con suerte, será una buena ronda.¿Por qué la gente comete errores en las pruebas en primer lugar?Si bien las pruebas automatizadas son una de las partes más importantes del proceso de desarrollo...Y las pruebas unitarias nos ahorran innumerables horas de pruebas manuales e innumerables errores que quedan atrapados en los conjuntos de pruebas...Muchas empresas no utilizan pruebas unitarias o no ejecutan suficientes pruebas.¿Sabía que la cobertura de prueba promedio de un proyecto es de ~40%, mientras que la recomendada es del 80%?Image descriptionEsto significa que mucha gente no está acostumbrada a ejecutar pruebas (especialmente casos de prueba complejos) y cuando no estás acostumbrado a hacer algo, eres más propenso a cometer un error.Entonces, sin más preámbulos, veamos algunos de los errores de prueba más comunes que veoCódigo duplicadoLas tres reglas más importantes del desarrollo de software son también las tres reglas más importantes de las pruebas.¿Cuáles son estas reglas? Reutilizar. Reutilizar. Reutilizar.Un problema común que veo es repetir la misma serie de comandos en cada prueba en lugar de moverlos a un enlace de ciclo de vida como beforeEach o afterEachEsto podría deberse a que el desarrollador estaba creando un prototipo o a que el proyecto era pequeño y el cambio insignificante. Estos casos son buenos y aceptables.Pero unos cuantos casos de prueba más tarde, el problema de la duplicación de código se vuelve cada vez más evidente.Y aunque esto es más bien un error de un desarrollador junior, el siguiente es similar pero mucho más astuto.Sobrecargar los hooks del ciclo de vidaEn la otra cara de la misma moneda, a veces estamos demasiado ansiosos por refactorizar nuestros casos de prueba y ponemos tantas cosas en los hooks del ciclo de vida sin pensarlo dos veces que no vemos el problema que nos estamos creando.A veces, los hooks del ciclo de vida crecen demasiado.Y cuando esto sucede......y necesitas desplazarte hacia arriba y hacia abajo para ir desde el hook al caso de prueba y viceversa...Esto es un problema y a menudo se lo denomina "fatiga de desplazamiento".Recuerdo haber sido culpable de esto en el pasado.Un patrón/práctica común para mantener el archivo legible cuando tenemos hooks de ciclo de vida inflados es extraer el código de configuración común en pequeñas funciones de fábrica.Entonces, imaginemos que tenemos algunas (docenas de) casos de prueba que se ven así:describe("authController", () => { describe("signup", () => { test("given user object, returns response with 201 status", async () => { // Arrange const userObject = { // several lines of user setup code }; const dbUser = { // several lines of user setup code }; mockingoose(User).toReturn(undefined, "findOne"); mockingoose(User).toReturn(dbUser, "save"); const mockRequest = { // several lines of constructing the request }; const mockResponse = { // several lines of constructing the response }; // Act await signup(mockRequest, mockResponse); // Assert expect(mockResponse.status).toHaveBeenCalled(); expect(mockResponse.status).toHaveBeenCalledWith(201); }); test("given user object with email of an existing user, returns 400 status - 1", async () => { // Arrange const userObject = { // several lines of user setup code }; const dbUser = { // several lines of user setup code }; const mockRequest = { // several lines of constructing the request }; const mockJson = jest.fn(); const mockResponse = { // several lines of constructing the response }; mockingoose(User).toReturn(dbUser, "findOne"); // Act await signup(mockRequest, mockResponse); // Assert expect(mockResponse.status).toHaveBeenCalled(); expect(mockResponse.status).toHaveBeenCalledWith(400); expect(mockJson).toHaveBeenCalled(); expect(mockJson).toHaveBeenCalledWith({ status: "fail", message: "Email taken.", }); }); }); });Podemos extraer la información de configuración repetida en sus propias funciones llamadas createUserObject, createDbUserObject y createMocksY luego las pruebas quedarían así:test("given user object, returns response with 201 status", async () => { const userObject = createUserObject(); const dbUser = createDbUserObject(); const [mockRequest, mockResponse] = createMocks(userObject); mockingoose(User).toReturn(undefined, "findOne"); mockingoose(User).toReturn(dbUser, "save"); await signup(mockRequest, mockResponse); expect(mockResponse.status).toHaveBeenCalled(); expect(mockResponse.status).toHaveBeenCalledWith(201); });Al extraer esos fragmentos de código en sus propias funciones de fábrica separadas, podemos evitar la fatiga del desplazamiento, mantener los enlaces del ciclo de vida ágiles y facilitar la navegación por el archivo y encontrar lo que estamos buscando.No priorizar los tipos de pruebas que ejecutasEsto tiene más que ver con bases de código grandes o enormes donde hay literalmente cientos o incluso miles de casos de prueba ejecutándose cada vez que una nueva serie de commits quiere fusionarse en la base de código.Image descriptionEn tales casos, ejecutar todos los conjuntos de pruebas puede llevar literalmente horas y es posible que no siempre tenga el tiempo o los recursos para hacerlo.Cuando el tiempo o los recursos están limitados, es importante elegir estratégicamente el tipo de prueba a priorizar. Generalmente, las pruebas de integración brindan mejores garantías de confiabilidad debido a su alcance más amplio. Por lo tanto, cuando se tiene que elegir entre los dos, suele ser una buena idea elegir las pruebas de integración en lugar de las pruebas unitarias.Image descriptionUsar lógica en tus casos de pruebaQueremos evitar la lógica en nuestros casos de prueba siempre que sea posible.Los casos de prueba solo deben tener una validación simple y evitar cosas como bloques try-catch o condicionales if-else.Esto mantiene tus pruebas limpias y enfocadas solo en el flujo esperado porque hace que las pruebas sean más fáciles de entender de un vistazo.La única excepción es cuando estás escribiendo funciones auxiliares o de fábrica que configuran escenarios para pruebas.Utilizar validaciones vagas en lugar de afirmaciones estrictasEsto suele ser una señal de que es posible que necesites refactorizar el fragmento de código que estás probando o que necesites hacer un ajuste menor en tus mocks.Por ejemplo, en lugar de comprobar si el valor es mayor que 1, deberías ser más específico y afirmar que el valor es 2.O, si está verificando los datos de un objeto Usuario, debe afirmar que cada dato es exactamente como lo espera, en lugar de simplemente verificar una coincidencia de ID.Los controles sueltos pueden enmascarar casos extremos que podrían fallar en el futuro.Implementación incorrecta del Mock BehaviorEste es difícil de encontrar y es por eso que puedes encontrar un ejemplo en cada código base.Es uno de los problemas de prueba más astutos pero comunes y es difícil notarlo a primera vista.Puede suceder cuando el comportamiento del mock está demasiado simplificado o cuando no refleja con precisión los casos extremos y las condiciones de error.Como resultado, las pruebas pueden pasar, pero no proporcionarán una indicación confiable de cómo funcionará el sistema bajo diversas condiciones, lo que resulta en errores futuros y problemas inesperados, y casos de prueba con comportamiento simulado que terminan haciendo más daño que bien.Espero este post te ayude a indetificar esas practicas que deberiamos evitar al momento de hacer pruebas.Profile@khriztianmoren

Por qué es tan difícil pasar el estado entre los componentes del cliente y del servidor

2024-03-28
javascriptreactweb-development

La forma en que representamos los componentes del servidor es diferente.Nada parecido a lo que estamos acostumbrados hasta ahora.Y debido a que es tan diferente, también cambia dónde manejamos el estado, cómo lo manejamos y cómo logramos dormir por la noche sabiendo que todas estas son cosas importantes que deberíamos saber desde el año pasado, pero la mayoría de nosotros somos completamente inconscientes.WHY?De hecho, los componentes del servidor impactan 3 de las partes más importantes del desarrollo web:PerformanceExperiencia del usuarioLa forma en que nosotros, los desarrolladores, escribimos código y diseñamos nuestras aplicaciones.No es algo que podamos ignorar o tomar a la ligera.Como puedes ver, he estado pensando mucho en ello y probablemente tú también lo hayas estado pensando. Todo desarrollador que valore su teclado está pensando en ello.Y está esta pregunta específica... Es como una pregunta del tipo “la gallina y el huevo”, principalmente porque ambas son preguntas que se hacen mucho.¿Cómo diablos manejo el estado en los componentes del servidor si no tengo acceso al estado en primer lugar?Antes de darte la respuesta, déjame explicarte el problema que nos ocupa. Considere lo que sucede cuando un componente del servidor solicita una nueva renderización.A diferencia de los componentes del cliente donde el estado se conserva entre renderizaciones, los componentes del servidor no pueden darse ese lujo. Como un juego pícaro, siempre empiezan desde cero.No existe ningún código o mecanismo inherente que pueda hacer que un componente del servidor recuerde el estado. El backend tiene todas esas bases de datos y patrones de diseño y todas esas funciones complejas y ¿para qué? Ni siquiera puede manejar el estado.¿Asi que que hacemos? ¿Utilizamos simplemente componentes de servidor en componentes completamente estáticos que no necesitan ningún estado? Si bien esta es una posible respuesta, también es un enfoque que limita la efectividad y el ajuste de los componentes del servidor en las aplicaciones web modernas. Entonces, lo estamos descartando.Porque todo lo que dije anteriormente tiene un inconveniente.Si bien es posible que el backend no maneje el estado del cliente como lo hace el cliente, sí maneja el estado de la aplicación. Entonces, en cierto modo, podemos manejar el estado en el servidor. Simplemente no de la forma en que lo piensas. Y, en realidad, no es una única manera.Y, en realidad, no es una única manera.Hay TRES formas de manejar el estado en el servidor.Cuál elegimos depende de lo que mejor se adapte a nuestras necesidades y situación actual. Y estas 3 formas son:Prop drilling desde el servidor a los componentescookiesstate hydrationAhora, otra pregunta del millón. ¿Por qué no podemos simplemente manejar todos los estados en el cliente?Esto se debe a que los componentes del servidor abogan por una separación de preocupaciones. Lo que en términos más simples significa que cada parte de la aplicación debe ocuparse de sus propios asuntos. Al desacoplar el estado del renderizado, no solo mejoramos el rendimiento, sino que también obtenemos más control sobre la experiencia del usuario.Profile@khriztianmoren

¿Seguirás utilizando componentes del lado del cliente en 2024?

2024-02-14
javascriptreactweb-development

Me encantan los componentes del servidor. Pero no son para todas las ocasiones. De hecho, usarlos en todas y cada una de las oportunidades que tengas es más como ablandar un bistec con el mismo martillo que usaste para clavar un alfiler.Dicho esto, también hay algunos casos en los que los componentes del servidor encajan como Cenicienta y su zapato.Dashboards & ReportsEn el caso de los paneles y los informes, se maximiza el rendimiento al procesar y representar todos los datos en el servidor y, al mismo tiempo, permitir que el cliente haga lo que se suponía que debía hacer en primer lugar.Si solo usamos componentes del cliente, le estamos descargando más tareas y haciendo que desempeñe más tareas de las que potencialmente puede manejar.Si procesó y representó los datos en el cliente, pasaría mucho tiempo esperando con un feo spinner burlándose de usted debido a todos los pasos adicionales que el cliente tiene que seguir para lograr el mismo resultado.Primero, necesitaría obtener los datos de su endpoint, que a su vez tendría que obtener datos de la base de datos, que a su vez tendría que obtener datos de sus registros.No sólo eso, sino que también hay que esperar pacientemente a que los datos lleguen al cliente, aunque llegue tarde.Y sólo una vez que llegan, el cliente puede comenzar a procesarlos y mostrárselos al usuario.Por eso, en este caso, es mejor tener los componentes bloqueados y renderizados directamente en el servidor.Y luego, el cliente puede obtener todos los widgets que su corazón electrónico desea, todos transmitidos en paralelo, lo que es una forma mucho más rápida y sencilla de realizar negocios.Blog PostsLas publicaciones de blog son algunos de los contenidos más estáticos que puedes encontrar. Después de todo, se trata principalmente de un montón de palabras, en orden, con alguna imagen, gif o meme ocasional aquí y allá.Con los componentes del servidor, estás renderizando previamente el contenido en el servidor, que es el mejor de los casos en términos de SEO porque se entrega rápido y completo.Este caso de uso anterior es lo que tiende a desequilibrar a los desarrolladores y confundirlos. Porque las publicaciones de blogs son lo primero en lo que también piensan cuando se trata de SSR. Entonces, si piensan en SSR y componentes de servidor cuando piensan en publicaciones de blog, es natural pensar que ambos son lo mismo o que pueden usarse indistintamente.Lo cual es total y absolutamente incorrecto y es un pecado digno de arder en el infierno por la eternidad, según mi blog post anterior.Pero al mismo tiempo tiene sentido desde el punto de vista de los resultados. Porque aunque sus enfoques son muy diferentes en la práctica, los resultados son bastante similares.Server-Side Data FetchingLa obtención de datos del lado del servidor es una excelente manera de darle a su código un impulso de seguridad en caso de que, de lo contrario, revele lógica o claves API que se supone deben permanecer ocultas o si está paranoico con respecto a cada pieza de información que posee.Puede utilizar este tipo de obtención de datos para acceder no sólo a su base de datos sino también a cualquier otra API que desee. Todo ello siendo astuto.Sin embargo, hay casos en los que los componentes del servidor NO son ideales y, de hecho, deben evitarse.Requisitos de alta interactividadEsta es una redacción elegante para cualquier cosa a la que le haces algo y le devuelves algo. Algo así como gelatina, pero no tanto.Algo potencialmente más familiar y más acorde con el desarrollo web en sí son elementos como formularios y botones.Estos componentes a menudo tienen que reaccionar de alguna manera a sus acciones, pueden tener su propio estado y comunicarse con otros componentes en el lado del cliente, lo que los convierte en el eslabón más débil cuando se trata de componentes de servidor.Stateful ComponentsSi lo tomas lo más literalmente posible y usas la definición que hemos estado usando hasta ahora, no hay manera de manejar el estado en un componente del servidor.Pero si entrecierras los ojos, inclinas la cabeza un poco hacia un lado, desenfocas un poco y respiras profundamente, podrás ver que esto es sólo una verdad a medias.En otro momento aprenderemos cuáles son los matices, pero por ahora digamos que los componentes del servidor NO tienen acceso al estado. Después de todo, no tienen acceso a hooks relacionados con el estado.ConclusiónLos componentes del servidor son una herramienta poderosa para escenarios específicos en el desarrollo web. Utilícelos para mejorar el rendimiento y la seguridad de tareas con uso intensivo de datos. Pero recuerde, es posible que no se adapten a todas las situaciones, especialmente para elementos interactivos o con estado.Profile@khriztianmoreno Hasta la próxima

Server Components Vs Server-side Rendering

2024-01-28
javascriptreactweb-development

¿Sabías que los componentes del servidor y el renderizado del lado del servidor son dos cosas completamente diferentes?Image descriptionY si bien van de la mano en muchos casos, hay igualmente muchos ejemplos en los que puedes y debes usar solo uno de ellos.Image descriptionAhora bien, para ser justos, dada la documentación en línea que la mayoría de los desarrolladores encuentran sobre los componentes del servidor y el renderizado del lado del servidor, el hecho de que asuman que estas dos cosas son iguales no es exactamente una sorpresa.(Esto también les da la excusa perfecta para evitar los componentes del servidor por completo, en lugar de enfrentar el hecho de que esto es algo que ya deberían saber usar bastante bien y que eventualmente tendrán que aprender de todos modos)Image descriptionDicho esto, los componentes del servidor tienen muchas ventajas sobre el renderizado del lado del servidor, especialmente cuando se trata de crear aplicaciones más grandes y complejas.Hablemos un poco más de las diferencias entre ambos.Server-Side RenderingLa representación del lado del servidor representa la página en el servidor. Pero, obviamente, eso no es realmente útil, así que profundicemos un poco más.La representación del lado del servidor representa la página en el servidor en el momento de la solicitud, lo que significa que cada vez que un cliente realiza una solicitud al servidor, como cuando un nuevo visitante llega a su página, el servidor vuelve a representar la misma página y la envía a el cliente.Y si bien esto es excelente para SEO, ya que incluso las páginas más dinámicas aparecen como estáticas a los ojos de los robots que las indexan y las usan para búsquedas, la representación del lado del servidor tiene muchos pasos entre el cliente que realiza la solicitud al servidor y La página finalmente se carga frente a ti.Primero, cuando la solicitud llega al servidor, el servidor representa estáticamente la página y la envía de regreso al cliente, donde el usuario obtiene una versión de su página que está desprovista de toda interactividad.Pero eso no es lo único que el servidor envía al cliente. Junto con el HTML de la página estática, el servidor envía sus condolencias junto con un gran paquete de código React que el cliente deberá ejecutar para que la página vuelva a ser dinámica.Pero ¿qué pasa cuando el 90% de nuestra página es estática?Podrías pensar que la respuesta correcta es “prácticamente nada” y no estarías exactamente equivocado, pero al igual que en la clase de Cálculo, pierdes puntos porque esta no es la respuesta que estaba buscando.En realidad, todavía se envía una gran cantidad de JavaScript al cliente y debe ejecutarse sin cambiar mucho en la página misma.Esto es una pérdida de tiempo y datos y es una de las principales razones por las que se crearon los componentes del servidor.(Lo que también significa que si está utilizando SSR como alternativa a los componentes del servidor, ha tenido un gran problema y es hora de cambiar su forma de actuar antes de que lo arrojen a una cárcel de "rendimiento lento").Server ComponentsLos componentes del servidor, como SSR, se representan en el servidor, pero tienen la capacidad única de incluir lógica del lado del servidor sin enviar ningún JavaScript adicional al cliente, ya que los componentes del servidor se ejecutan en el servidor.Esto significa que mientras en SSR el código JavaScript se ejecuta en el cliente, en Server Components, el código se ejecuta directamente en el servidor. Y el cliente solo recibe la salida del código a través de la carga útil del servidor, como un bebé al que le mastican la comida.Entonces, en pocas palabras, la diferencia entre componentes de servidor y renderizado del lado del servidor tiene que ver con cuándo y cómo se ejecuta el código. En el caso de los componentes del servidor, no es necesario enviar ni manejar código adicional en el lado del cliente porque ya lo ejecutamos en el servidor.El único código necesario es si está uniendo los componentes del servidor y del cliente y el cliente tiene que unir los dos.El gran beneficio de los componentes de servidor es que ofrecen un mayor rendimiento porque necesitan menos JavaScript del lado del cliente y descargan todo el procesamiento y la recuperación de datos al servidor mientras el cliente puede relajarse y beber Aperol Spritz hasta que llegue el HTML renderizado.En ese momento, el cliente simplemente se lo muestra al usuario final y se lleva todo el crédito por el arduo trabajo realizado por el servidor.Y si bien esto puede parecer un poco complejo en este momento, todo se aclarará a medida que aprenda más sobre los componentes del servidor. Lo cual es algo que realmente no se puede evitar, ya que se están volviendo cada vez más populares en casos de uso como:Tener muchos cálculos pesados ​​que necesitan mucho procesamientoAcceso API privado (para mantener el secreto… secret)Cuando la mayor parte del lado del cliente ya es estático y sería un desperdicio enviar más JavaScript al clienteConclusiónSi bien los componentes de servidor pueden parecer desalentadores en este momento, en su mayoría son algo nuevo y extraño. Una vez que los conozcas mejor y aprendas algunos de los conceptos básicos, te darás cuenta de que no son tan complejos como parecen.La curva de aprendizaje no es tan pronunciada como podría pensar y solo porque tengan "sever" en el nombre, no significa que tengan que ser algo extraño y críptico de lo que los desarrolladores frontend debamos mantenernos alejados. De hecho, son bastante similares a los componentes del cliente e incluso más livianos ya que carecen de elementos como enlaces de estado, etc.Profile@khriztianmoren

Clonar un objeto en JavaScript - 4 mejores formas [Ejemplos]

2023-06-18
javascriptprogrammingweb-development

Clonar un objeto en JavaScript significa crear una copia idéntica de un objeto existente. Esto significa que el nuevo objeto tendrá los mismos valores para cada propiedad, pero será un objeto diferente.¿Por qué es importante clonar un objeto en javascript?Clonar un objeto en javascript es importante para preservar el estado original de un objeto y evitar la propagación de los cambios. Esto es especialmente útil cuando hay varias instancias de un objeto que se comparten entre varias partes de la aplicación. Clonar el objeto original garantiza que las otras instancias no se vean afectadas por los cambios realizados en el objeto original. Esto también permite a los desarrolladores usar una sola instancia del objeto y crear una copia única para cada parte de la aplicación. Esto evita tener que crear cada vez una nueva instancia del objeto, lo que ahorra tiempo y recursos.¿Cómo clonar un objeto?Para clonar un objeto JavaScript correctamente, tienes 4 opciones diferentes:Usar la función structuredClone()Usar el spread operatorLlamar la función Object.assign()Usar JSON parsing.const data = { name: "khriztianmoreno", age: 33 }; // 1 const copy4 = structuredClone(data); // 2 const copy1 = { ...data }; // 3 const copy2 = Object.assign({}, data); // 4 const copy3 = JSON.parse(JSON.stringify(data));1. structuredClone()Crea un clon profundo de un valor dado utilizando el algoritmo de clonación estructurada.const original = { someProp: "with a string value", anotherProp: { withAnotherProp: 1, andAnotherProp: true, }, }; const myDeepCopy = structuredClone(original);2. spread operatorEl operador de propagación (...) permite expandir un objeto o un arreglo en una lista de elementos individuales, y se utiliza para crear una copia de un objeto.const original = { name: "khriztianmoreno", age: 33 }; const clone = { ...original };En el ejemplo anterior, se esta creando un nuevo objeto clone a partir de los valores del objeto original, es importante notar que esto solo hace una copia superficial, si el objeto original contiene objetos o arreglos dentro de el, estos no serán clonados sino que se asigna la referencia del objeto original.También se puede utilizar para clonar arreglos de la siguiente manera:const original = [1, 2, 3, 4]; const clone = [...original];3. Object.assignLa función Object.assign() es otra forma de clonar objetos en JavaScript. La función toma un objeto destino como primer argumento, y uno o más objetos fuente como argumentos adicionales. Copia las propiedades enumerables de los objetos fuente al objeto destino.const original = { name: "khriztianmoreno", age: 33 }; const clone = Object.assign({}, original);4. JSON parsingEl método JSON.parse() y JSON.stringify() es otra forma de clonar objetos en JavaScript. El método JSON.stringify() convierte un objeto en una cadena de texto en formato JSON, mientras que el método JSON.parse() convierte una cadena de texto en formato JSON en un objeto de JavaScript.const original = { name: "khriztianmoreno", age: 33 }; const clone = JSON.parse(JSON.stringify(original));ConclusionesVentajas de clonar un objeto en javascriptEl clonado de objetos permite al desarrollador crear una copia de un objeto existente sin tener que redefinir todos los valores del objeto. Esto significa que el desarrollador puede ahorrar tiempo y esfuerzo al no tener que recrear un objeto desde cero.El clonado de objetos también permite al desarrollador crear una versión modificada de un objeto existente. Por ejemplo, un desarrollador puede modificar los valores de un objeto existente para crear una versión personalizada. Esto es útil para ahorrar tiempo al no tener que reescribir el código para crear un objeto desde cero.El clonado de objetos también permite al desarrollador crear una versión mejorada de un objeto existente. Por ejemplo, un desarrollador puede añadir nuevas propiedades a un objeto existente para mejorar su funcionalidad.El clonado de objetos también ofrece una forma de hacer copias de seguridad de los objetos. Esto significa que si el objeto existente se ve afectado por una falla de software, el desarrollador puede recurrir a la copia de seguridad para recuperar los valores originales.Desventajas de clonar un objeto en javascriptClonar un objeto en Javascript puede ser una tarea útil, pero también hay algunos inconvenientes que deben tenerse en cuenta. El primero es el tiempo de ejecución. El clonado de objetos en Javascript puede ser un proceso lento, especialmente si el objeto es grande. Esto puede llevar a una mala experiencia de usuario si se está intentando clonar un objeto mientras se ejecuta una aplicación.Otra desventaja del clonado de objetos en Javascript es que no se pueden clonar objetos complejos. Esto significa que los objetos que contienen referencias a otros objetos no se pueden clonar correctamente. Esto puede ser un problema si se está intentando clonar un objeto que contiene referencias a otros objetos importantes, ya que el clon no tendrá estas referencias.Por último, el clonado de objetos en Javascript también puede llevar a problemas de seguridad si se clonan objetos que contienen información sensible. El clon puede contener la misma información que el objeto original, lo que puede ser un riesgo para la seguridad si se comparte el clon con otros usuarios.¡Eso es todo amigxs! ¡Espero que este artículo lo ayude a comprender las diferentes opciones que tenemos a la hora de clonar un objecto/arraglo en javascript.Profile@khriztianmorenoHasta la próxima.PD: Este articulo fue escrito completamente usando Inteligencia Aritifcia

Cómo usar los métodos Call, Apply y Bind en javascript

2023-05-12
javascriptweb-developmentprogramming

En este artículo, veremos qué son los métodos call, apply y bind en javascript y por qué existen.Antes de saltar, necesitamos saber que es this en javascript, en este post puedes profundizar un poco más.Call, Apply and BindEn Javascript, todas las funciones tendrán acceso a una palabra clave especial llamada this, el valor de this apuntará al objeto en el que se ejecuta esa función.¿Qué son estos métodos call, apply y bind?Para decirlo de una manera simple, todos estos métodos se usan para cambiar el valor de this dentro de una función.Entendamos cada método en detalle.call()Usando el método call, podemos invocar una función, pasando un valor que será tratado como this dentro de ella.const obj = { myName: "khriztianmoreno", printName: function () { console.log(this.myName); }, }; obj.printName(); // khriztianmoreno const newObj = { myName: "mafeserna", }; obj.printName.call(newObj); //mafesernaen el ejemplo anterior, estamos invocando el método call en la función printName al pasar newObj como parámetro, por lo que ahora this dentro de printName apunta a newObj, por lo tanto, this.myName imprime mafeserna.¿Cómo pasar argumentos a funciones?El primer argumento del método call es el valor al que apunta this dentro de la función, para pasar argumentos adicionales a esa función, podemos comenzar a pasarlo desde el segundo argumento del método call.function foo(param1, param2) {} foo.call(thisObj, arg1, arg2);dónde:foo es la función que estamos invocando al pasar el nuevo valor this que es thisObjarg1, arg2, son los argumentos adicionales que tomará la función foo ( param1= arg1 , param2 = arg2 )apply()La función apply es muy similar a la función call. La única diferencia entre call y apply es la diferencia en cómo se pasan los argumentos.call — pasamos argumentos como valores individuales, comenzando desde el segundo argumentoapply — los argumentos adicionales se pasarán como un arreglofunction sayHello(greet, msg) { console.log(`${greet} ${this.name} ! ${msg}`); } const obj = { name: "khriztianmoreno", }; // Call sayHello.call(obj, "Hello", "Good Morning"); // Hello khriztianmoreno ! Good Morning // Apply sayHello.apply(obj, ["Hello", "Good Morning"]); // Hello khriztianmoreno ! Good Morningen el ejemplo anterior, tanto el método call como apply en la función sayHello están haciendo lo mismo, la única diferencia es cómo estamos pasando argumentos adicionales.bind()A diferencia de los métodos call y apply, bind no invocará la función directamente, sino que cambiará el valor this dentro de la función y devolverá la instancia de la función modificada.Podemos invocar la función devuelta más tarde.function sayHello() { console.log(this.name); } const obj = { name: "khriztianmoreno" }; // it won't invoke, it just returns back the new function instance const newFunc = sayHello.bind(obj); newFunc(); // khriztianmorenopasando argumentos adicionales: pasar argumentos adicionales en bind funciona de manera similar al método call, podemos pasar argumentos adicionales como valores individuales a partir del segundo argumento del método bind.function sayHello(greet) { console.log(`${greet} ${this.name}`); } const obj = { name: "khriztianmoreno" }; const newFunc = sayHello.bind(obj, "Hello"); newFunc(); // Hello khriztianmorenoEn el caso del método bind, podemos pasar argumentos adicionales de dos formas:Al llamar al método bind en sí mismo, podemos pasar argumentos adicionales junto con el valor de this a esa función.Otra forma es que podemos pasar argumentos adicionales mientras invocamos la función de retorno del método bind.Podemos seguir cualquiera de las formas anteriores y funciona de manera similar sin ninguna diferencia en la funcionalidad.function sayHello(greet) { console.log(`${greet} ${this.name}`); } const obj = { name: "khriztianmoreno" }; const newFunc1 = sayHello.bind(obj, "Hello"); newFunc1(); // Hello khriztianmoreno const newFunc2 = sayHello.bind(obj); newFunc2("Hello"); // Hello khriztianmorenoNOTA: si no pasamos ningún valor o pasamosnull mientras llamamos a los métodos call, apply, bind, entonces esta función interna de llamada apuntará al objeto global.function sayHello() { // executing in browser env console.log(this === window); } sayHello.call(null); // true sayHello.apply(); // true sayHello.bind()(); // trueNo podemos usar los métodos call, apply y bind en las funciones flecha para cambiar el valor de this, porque las funciones de flecha no tienen su propio contexto this.El this dentro de la función de flecha apuntará a la función externa/principal en la que está presente.Por lo tanto, aplicar estos métodos en la función de flecha no tendrá ningún efecto.¡Eso es todo amigxs! ¡Espero que este artículo lo ayude a comprender qué son los métodos call(), apply() y bind() en javascript.!Profile@khriztianmoren

Hacks for effective Fullstack development with React and Node

2023-04-17
javascriptnodejsreact

Hoy te mostraré un flujo de trabajo óptimo para un desarrollo efectivo con Node.js y React. Si alguna vez ha trabajado en un proyecto con varios archivos package.json, es posible que conozca el dolor de hacer malabarismos con varias pestañas de terminal, recordar qué comandos inician qué servidor o manejar los errores de CORS.Afortunadamente, hay algunas herramientas disponibles que pueden aliviar algunos de estos dolores de cabeza.FullstackConfiguración de Monorepo para React y NodeDigamos que estamos trabajando en un monorepo con dos archivos package.json: uno está en un directorio client para un front-end de React impulsado por Create React App, y uno está en la raíz del repositorio para un back-end de Node que expone un API que utiliza nuestra aplicación React. Nuestra aplicación React se ejecuta en localhost:3000 y nuestra aplicación Node se ejecuta en localhost:8080. Ambas aplicaciones se inician con npm startDado que tenemos dos archivos package.json, esto significa que para que nuestro front-end y back-end estén en funcionamiento, debemos asegurarnos de haber ejecutado npm install y npm start tanto en el directorio raíz como en el directorio del cliente. Así es como simplificamos esto.1. Ejecutar dos servidores al mismo tiempoUna mejora que podemos hacer en nuestro flujo de trabajo de desarrollo es agregar una herramienta de compilación para ejecutar varios comandos npm al mismo tiempo para ahorrarnos la molestia de ejecutar npm start en varias pestañas de terminal. Para hacer esto, podemos agregar un paquete npm llamado concurrently a la raíz de nuestro proyecto.En la raíz de nuestro proyecto, lo instalaremos como una dependencia de desarrollo.npm install -D concurrentlyLuego, en nuestras secuencias de comandos root package.json, actualizaremos nuestra secuencia de comandos start para usarlas simultáneamente.{ "name": "my-app", "version": "1.0.0", "main": "index.js", "scripts": { "start": "concurrently --kill-others-on-fail npm run server npm run client", "server": "node index.js", "client": "cd client && npm start" }, "dependencies": { "express": "^4.17.1" }, "devDependencies": { "concurrently": "^6.0.1" } }Ahora, tenemos tres scripts npm:npm run server inicia nuestra aplicación Node,npm run client ejecuta npm start en el directorio del client para iniciar nuestra aplicación React,npm start ejecuta npm run server y npm run client al mismo tiempo.2. Instalar las dependencias de front-end y back-end con un solo comandoOtro aspecto de nuestro flujo de trabajo que podemos mejorar es la instalación de dependencias. Actualmente, necesitamos ejecutar manualmente npm install para cada archivo package.json que tenemos al configurar el proyecto. En lugar de pasar por esa molestia, podemos agregar un postinstall script a nuestro package.json raiz para ejecutar automáticamente npm install en el directorio del client después de que la instalación haya finalizado en el directorio raíz.{ "name": "my-app", "scripts": { ..., "postinstall": "cd client && npm install" }, }Ahora, cuando instalamos nuestro monorepo, todo lo que tenemos que hacer para ponerlo en marcha es ejecutar npm install y luego npm start en la raíz del proyecto. No es necesario ingresar a ningún otro directorio para ejecutar otros comandos.3. Solicitudes API proxy desde el back-endComo mencione anteriormente, nuestro back-end de Node expone los endpoints del API que utilizara nuestra aplicación React. Digamos que nuestra aplicación Node tiene un endpoint /refresh_token.Fuera de la caja, si intentáramos enviar una solicitud GET a http://localhost:8080/refresh_token desde nuestra aplicación React en http://localhost:3000, nos encontraríamos con problemas de CORS. CORS significa intercambio de recursos de origen cruzado.Por lo general, cuando encuentra errores de CORS, es porque está tratando de acceder a los recursos de otro dominio (es decir, http://localhost:3000 y http://localhost:8080), y el dominio del que está solicitando recursos no está permitido.Para decirle al servidor de desarrollo que envíe por proxy cualquier solicitud desconocida a nuestro servidor API en desarrollo, podemos configurar un proxy en el archivo package.json de nuestra aplicación React. En client/package.json, agregaremos un proxy para http://localhost:8080 (donde se ejecuta nuestra aplicación Node).{ "name": "client-app", "proxy": "http://localhost:8080", "dependencies": { "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, ... }Ahora, si reiniciamos el servidor y configuramos una solicitud al endPoint /refresh_token de nuestra aplicación Node (sin http://localhost:8080) usando fetch(), el error CORS debería resolverse.fetch("/refresh_token") .then((res) => res.json()) .then((data) => console.log(data)) .catch((err) => console.error(err));La próxima vez que trabaje en un proyecto monorepo como este, pruebe estos tres consejos para optimizar su flujo de trabajo de desarrollo.¡Eso es todo amigxs! ¡Espero que esto te ayude a convertirte en un o una mejor dev!Profile@khriztianmorenoHasta la próxima

Introducción a los archivos .env

2023-03-09
javascriptweb-developmentprogramming

Imagínate tener que pagar cerca de $148 millones por una violación de datos que expuso los datos de unos 57 millones de usuarios 😱😰Pues eso fue lo que le sucedio a Uber, no hace mucho tiempo, y el culpable fue nada más y nada menos que un secreto codificado publicado abiertamente para que cualquier mal actor lo explote.Por eso en este post, vamos a conocer que son y como podríamos trabajarlos en nuestros proyecto con javascript.envContextoHoy en día, millones de desarrolladores de software mantienen sus secretos (es decir, credenciales como claves de acceso y tokens a los servicios utilizados por los programas) seguros con archivos .env.Para aquellos que no estén familiarizados con el tema, los archivos .env se introdujeron en 2012 como parte de una solución al problema del secreto codificado mencionado en el párrafo introductorio anterior.En lugar de enviar los secretos junto con su código base a la nube, los desarrolladores ahora podrían enviar su código base a la nube y mantener sus secretos separados en sus máquinas en formato clave-valor en archivos .env; esta separación redujo el riesgo de que los malos actores tuvieran en sus manos las credenciales confidenciales en la nube.Para ejecutar programas, los desarrolladores ahora solo tendrían que jalar su código base más reciente del repositorio remoto e inyectar los secretos contenidos en sus archivos .env locales en el código jalado.A menos que un equipo de desarrollo sea pequeño y "desigual", que no se preocupe mucho por DevOps, normalmente mantiene múltiples "entornos" para su base de código para garantizar que los cambios se prueben bien antes de enviarse a producción para interactuar con los usuarios finales. En el caso de varios entornos, los desarrolladores pueden optar por emplear varios archivos .env para almacenar las credenciales, uno para cada uno de esos entornos (por ejemplo, un archivo .env para contener las claves de la base de datos de desarrollo y otro para contener las claves de la base de datos de producción).Para resumir, los archivos .env contienen credenciales en formato clave-valor para los servicios utilizados por el programa que están creando. Están destinados a almacenarse localmente y no cargarse a repositorios de códigos en línea para que todos los lean. Cada desarrollador de un equipo normalmente lleva uno o más archivos .env para cada entorno.UsoEn este post, veremos cómo usar un archivo .env en un proyecto básico, asumiendo que está usando Node.js y git para el control de versiones; esto también debería aplicarse a otros lenguajes. Siéntase libre de omitir esta sección si no está interesado en los aspectos técnicos de cómo usar un archivo .env.Para comenzar, diríjase a la raíz de la carpeta de su proyecto y cree un archivo .env vacío que contenga las credenciales que le gustaría inyectar en su base de código. Puede verse algo como esto:SECRET_1=924a137562fc4833be60250e8d7c1568 SECRET_2=cb5000d27c3047e59350cc751ec3f0c6A continuación, querrá ignorar el archivo .env para que no se confirme en git. Si aún no lo ha hecho, cree un archivo .gitignore. Debe tener un aspecto como este:.envAhora, para inyectar los secretos en su proyecto, puede usar un módulo popular como dotenv; analizará el archivo .env y hará que sus secretos sean accesibles dentro de su base de código bajo el objeto de process. Continúe e instale el módulo:npm install dotenvImporte el módulo en la parte superior del script de inicio para su base de código:require(‘dotenv’).config()Eso es todo, ahora puede acceder a los secretos en cualquier lugar de su base de código:// display the value of SECRET_1 into your code console.log(process.env.SECRET_1); // -> 924a137562fc4833be60250e8d7c1568 // display the value of SECRET_2 into your code console.log(process.env.SECRET_2); // -> cb5000d27c3047e59350cc751ec3f0c6Excelente. Ha agregado con éxito un archivo .env a su proyecto con algunos secretos y ha accedido a esos secretos en su base de código. Además, cuando envías tu código a través de git, tus secretos permanecerán en tu máquina.DesafíosAunque simples y potentes, los archivos .env pueden ser problemáticos cuando se administran de manera incorrecta en el contexto de un equipo más grande.Imagine tener que distribuir y rastrear cientos de claves a su equipo de desarrollo de software.En un nivel simplificado, entre Developer_1 y Developer_2, esto es lo que podría pasar:Developer_1 podría agregar una clave API a su archivo .env local y olvidarse de informar a Developer_2 para que la agregue al suyo; esto le costó a Developer_2 15 minutos en el futuro depurando por qué su código se bloquea solo para darse cuenta de que se debe a la clave API faltante.Developer_2 podría pedirle a Developer_1 que le envíe la clave API para que pueda agregarla a su archivo .env, después de lo cual Developer_1 puede optar por enviarla por mensaje de texto o correo electrónico; esto ahora pone innecesariamente a su organización en riesgo de que los malos actores como Developer_2 esperen precisamente para interceptar la clave API.Desafortunadamente, estos desafíos son comunes e incluso tienen un nombre: secret sprawl (expansión secreta).En los últimos años, muchas empresas han intentado solucionar este problema. HashiCorp Vault es un producto que almacena secretos de forma segura para grandes empresas; sin embargo, es demasiado costoso, engorroso y francamente excesivo para configurarlo para el desarrollador promedio que solo necesita una forma rápida y segura de almacenar estos secretos.Existen soluciones más simples, como Doppler y el nuevo dotenv-vault, pero a menudo carecen de la infraestructura de seguridad necesaria para obtener una adopción masiva.Déjame en los comentarios cuales herramientas o servicios utilizas para solucionar de mara fácil y segura el secret sprawl (expansión secreta).¡Eso es todo amigxs! ¡Espero que esto te ayude a convertirte en un o una mejor dev!Profile@khriztianmoreno �

Algunos métodos más allá del console.log en Javascript

2023-02-17
javascriptweb-developmentprogramming

Some methods beyond console.log in JavascriptA menudo, durante la depuración, los desarrolladores javascript solemos usar el método console.log() para imprimir valores. Pero hay algunos otros métodos de consola que te hacen la vida mucho más fácil. ¿Quieres saber cuáles son estos métodos? ¡Vamos a conocerlos!1. console.table()Mostrar arreglos u objetos largos es un dolor de cabeza usando el método console.log(), pero con console.table() tenemos una forma mucho más elegante de hacerlo.// Matrix const matrix = [ ["apple", "banana", "cherry"], ["Rs 80/kg", "Rs 100/kg", "Rs 120/kg"], ["5 ⭐", "4 ⭐", "4.5 ⭐"], ]; console.table(matrix); // Maps class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } } const family = {}; family.mother = new Person("Jane", "Smith"); family.father = new Person("John", "Smith"); family.daughter = new Person("Emily", "Smith"); console.table(family);console.table()2. console.trace()¿Tiene problemas para depurar una función? ¿Te quedas preguntándote cómo fluye la ejecución? ¡console.trace() es tu amigo!function outerFunction() { function innerFunction() { console.trace(); } innerFunction(); } outerFunction();console.trace()3. console.error() y console.warn()¿Cansado de logs/registros aburridos? Dale sabor a las cosas con console.error() y console.warn()console.error("This is an error message"); console.warn("This is a warning message"); console.log("This is a log message");console.error()4. console.assert()¡Esta es otra herramienta brillante para la depuración! Si la aserción falla, la consola imprimirá el seguimiento/trace.function func() { const a = -1; console.assert(a === -1, "a is not equal to -1"); console.assert(a >= 0, "a is negative"); } func();console.assert()5. console.time(), console.timeEnd(), y console.timeLog()¿Necesita comprobar cuánto tarda algo? ¡Los métodos del temporizador están ahí para rescatarte!console.time("timeout-timer"); setTimeout(() => { console.timeEnd("timeout-timer"); }, 1000); setTimeout(() => { console.timeLog("timeout-timer"); }, 500);console.time()NOTA: Los setTimeouts no se ejecutan de inmediato, lo que genera una pequeña desviación del tiempo esperado.¡Eso es todo amigxs! ¡Espero que esto te ayude a convertirte en un o una mejor dev!Profile@khriztianmoreno en Twitter y GitHu

Un viaje a las Single Page Application a través de React y JavaScript

2022-09-18
javascriptweb-developmenttalks

El pasado mes de junio, tuve la oportunidad de compartir nuevamente en persona con la comunidad de medellinjs a la cual aprecio demasiado.MedellinJSEsta vez, estuve hablando sobre los conceptos de javascript que son necesarios entender y conocer antes de enfrentarse a trabajar con una Single Page Application (SPA).<iframe width="560" height="315" src="https://www.youtube.com/embed/6opIHgRqWPo?si=xFM0sbf6w8qKQkR3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoren

React useEffect

2022-09-05
javascriptreacthooks

useEffect es probablemente el hook más confuso e incomprendido en React. Hoy quiero aclararte eso.Usamos hooks todo el tiempo en Make It Real y comprender useEffect es crucial si vamos a escribir código React de estilo moderno.A continuación veremos:¿Qué es useEffect?Cómo ejecutar un effect(efecto) en cada renderCómo ejecutar un efecto solo en el primer renderCómo ejecutar un efecto en el primer render y volver a ejecutarlo cuando cambia una "dependencia”Cómo ejecutar un efecto con limpieza¿Qué es useEffect?El hook useEffect nos permite realizar side effects(efectos secundarios) en nuestros componentes de función. Los side effects son esencialmente cualquier cosa en la que queremos que suceda una acción "imperativa". Esto es cosas como:Llamadas a APIActualizar el DOMsuscribirse a event listeners(oyentes de eventos)Todos estos son efectos secundarios que podríamos necesitar que un componente haga en diferentes momentos.Ejecutar useEffect en cada renderEl hook useEffect no devuelve ningún valor, sino que toma dos argumentos. Siendo el primero obligatorio y el segundo opcional. El primer argumento es la función callback del efecto que queremos que ejecute Hook (es decir, el efecto en sí). Supongamos que queríamos colocar un mensaje console.log() dentro del callback del useEffect.import { useEffect } from "react"; export const FunctionComponent = () => { useEffect(() => { console.log("run for every componentrender"); }); return ( // ... ); }De forma predeterminada, el efecto establecido en el hook useEffect se ejecuta cuando el componente se renderiza por primera vez y después de cada actualización. Si ejecutamos el código anterior, notaremos que se genera el mensaje console.log('run for every componentrender') a medida que se renderiza nuestro componente. Si nuestro componente alguna vez se volviera a renderizar (por ejemplo, de un cambio de estado con algo como useState), el efecto se ejecutaría nuevamente.A veces, volver a ejecutar un efecto en cada renderizado es exactamente lo que quieres. Pero la mayoría de las veces, solo desea ejecutar el efecto en ciertas situaciones, como en el primer renderizado.Cómo ejecutar el useEffect solo en el primer renderEl segundo argumento del hook useEffect es opcional y es una lista de dependencias que nos permite decirle a React que omita la aplicación del efecto solo hasta que se den ciertas condiciones. En otras palabras, el segundo argumento del hook useEffect nos permite limitar cuándo se ejecutará el efecto. Si simplemente colocamos un array vacío como segundo argumento, así es como le decimos a React que solo ejecute el efecto en el renderizado inicial.import { useEffect } from "react"; export const FunctionComponent = () => { useEffect(() => { console.log("run only for first component render (i.e.component mount)"); }, []); return ( // ... ); }Con el código anterior, el mensaje console.log() solo se activará cuando el componente se monte por primera vez y no se volverá a generar, incluso si el componente se vuelve a renderizar varias veces.Esto es mucho más "eficiente" que ejecutar en cada renderizado, pero ¿no hay un término medio feliz? ¿Qué pasa si queremos rehacer el efecto, si algo cambia?Ejecutar el useEffect en el primer render y volver a ejecutarlo cuando cambie la dependenciaEn lugar de hacer que un efecto se ejecute una vez al principio y en cada actualización, podemos intentar restringir el efecto para que se ejecute solo al principio y cuando cambie cierta dependencia.Supongamos que queríamos lanzar un mensaje console.log() cada vez que cambiara el valor de una propiedad de estado. Podemos lograr esto colocando la propiedad de estado como una dependencia del callback del efecto. Mira el siguiente ejemplo de código:import { useState, useEffect } from "react"; export const FunctionComponent = () => { const [count, setCount] = useState(0); useEffect(() => { console.log( "run for first component render and re-run when 'count' changes" ); }, [count]); return ( <button onClick={() => setCount(count + 1)}> Click to increment count and trigger effect </button> ); };Arriba, tenemos un botón en el template del componente responsable de cambiar el valor de la propiedad de estado de count cuando se hace click. Cada vez que se cambie la propiedad de estado count (es decir, cada vez que se haga click en el botón), notaremos que se ejecuta el callback del efecto y se activa el mensaje console.log().Ejecutar efecto con limpiezaSe ejecuta un callbak de efecto cada vez en el procesamiento inicial y cuando especificamos cuándo se debe ejecutar un efecto. El hook useEffect también brinda la capacidad de ejecutar una limpieza después del efecto. Esto se puede hacer especificando una función de retorne al final de nuestro efecto.import { useState, useEffect } from "react"; export const FunctionComponent = () => { const [count, setCount] = useState(0); useEffect(() => { console.log( "run for first component render and re-run when 'count' changes" ); return () => { console.log("run before the next effectand when component unmounts"); }; }, [count]); return ( <button onClick={() => setCount(count + 1)}> Click to increment count and trigger effect </button> ); };En el ejemplo anterior, notaremos que el mensaje de la función de limpieza se activa antes de que se ejecute el efecto deseado. Además, si nuestro componente alguna vez se desmonta, la función de limpieza también se ejecutará.Un buen ejemplo de cuándo podríamos necesitar una limpieza es cuando configuramos una suscripción a nuestro efecto, pero queremos eliminar la suscripción cada vez que se realice la próxima llamada de suscripción, para evitar memory leaks.A good example of when we might need a cleanup is when we set up a subscription in our effect but want to remove the subscription whenever the next subscription call is to be made, to avoid memory leaks.Estas son principalmente todas las diferentes formas en que el hook useEffect se puede utilizar para ejecutar efectos secundarios en componentes. Te invito a ver esta guia visual de useEffect de ALEX SIDORENKO que ilustra estos conceptos a través de una serie de GIF es a la vez inteligente y eficaz, especialmente para los estudiantes visuales. También hay una visualización de cómo funcionan las funciones de primera clase si quieres más.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

Por qué Storybook? la herramienta de desarrollo de componentes utilizada por más de 30,000 proyectos

2022-08-22
javascriptstorybookreact

Storybook es una herramienta para desarrollar componentes e interfaces de usuario más rápido que nunca. Storybook es increíblemente versátil: puedes usarlo con una variedad de librerías y frameworks de JavaScript, no solo React. Está disponible para Vue, React, Svelte, Angular y Ember.js.StorybookSi has estado desarrollando tus componentes a la antigua usanza, en tu editor de texto o IDE, una herramienta como Storybook te permite desbloquear una mayor productividad al desarrollar componentes. A continuación, aprenderád qué es Storybook, cómo funciona y si es adecuado para tu equipo.Los problemas de desarrollar componentes de forma tradicionalComencemos observando la fricción involucrada con el proceso típico de desarrollo de componentes:Recibes una tarea para desarrollar una función: digamos que es un formulario en la página de pago.Luego, debes configurar el entorno de desarrollo: conectarse a la VPN, ejecutar el backend, ejecutar el frontend, etc.Finalmente, llega a la página en la que vivirá el feature (característica).Es engorroso navegar entre varias páginas, completar formularios y hacer clic en botones cada vez que tiene que llegar a donde debería estar la función. A veces, sus componentes tienen varios estados, por ejemplo, loading, success, y error. No siempre es fácil replicar todos los estados de un componente, lo que lo lleva a modificar el código del componente solo para forzar un estado específico.Storybook aísla tus componentes: depuración de componentes más fácilEs posible que haya pasado por estas situaciones y se haya encontrado con el dolor que implica este tipo de flujo de trabajo de desarrollo de componentes.La mayor parte del tiempo, mientras desarrollas, deseas concentrarte en el componente que estás creando, por lo que otros elementos en una página se vuelven ruido. Tener una forma de acceder rápidamente a cualquier componente o función, y también poder simular todos los casos de uso, es increíblemente beneficioso y te ahorra mucho tiempo.Storybook te brinda este tipo de aislamiento de componentes para que puedas trabajar solo en el componente que tienes en mente, sin tener que interactuar con otros componentes.¿Qué es Storybook?Storybook es una herramienta de código abierto que te ayuda a desarrollar componentes de interfaz de usuario de forma aislada. Se ejecuta en tu base de código, pero por separado de tu aplicación, por lo que funciona como una caja de arena, lo que permite a los desarrolladores no distraerse con API incompletas, datos inestables y otras dependencias externas. Se integra con marcos como React, Vue, Svelte, Angular y otros.Piense en Storybook como un libro real, con un índice de páginas que se vincula a los componentes de la interfaz de usuario. Cada componente tiene historias (stories) que contar sobre sí mismo, y estas historias representan los diferentes estados de la interfaz de usuario de ese componente. Independientemente de la situación, incluso si está desconectado, podrás acceder a esa página y encontrar y jugar fácilmente con los componentes.Debido a sus ventajas de productividad y colaboración, Storybook es utilizado por más de 30_000 proyectos de código abierto, especialmente bibliotecas de componentes. Sin embargo, muchas empresas de tecnología, como Airbnb, Atlassian y JetBrains, se encuentran entre sus usuarios.¿Para quién es Storybook?Algunas personas parecen pensar que Storybook es una herramienta solo para desarrolladores de bibliotecas de componentes y eso ciertamente no lo es.Storybook nos ayuda a construir desde el componente más simple y atómico, como un botón o un input, hasta características complejas o páginas completas.Dado que Storybook nos ayuda a resumir la interfaz de usuario de las aplicaciones, los diseñadores y los QA pueden beneficiarse de ello. Con Storybook, puedes facilitar el desarrollo de un sistema de diseño y compartir un solo lenguaje con los diseñadores. Los QA pueden obtener una descripción general y probar las funcionalidades de forma aislada. Storybook incluso se puede usar para demostrar la funcionalidad a las partes interesadas, como si fuera un demo.Muchas empresas han hecho públicos sus Storybooks. No son solo inspiración, sino una guía de aprendizaje para equipos nuevos en Storybook y puedes encontrar una lista de Storybooks públicos aquí.Como funcionaDesde un aspecto técnico, Storybook es esencialmente una aplicación React que se ejecuta en tu base de código, por separado de tu aplicación principal. Lo inicia ejecutando un comando CLI. Buscará archivos en tu base de código que contengan una extensión .stories.*, reunirá todos esos componentes y los mostrará en una interfaz de usuario agradable.Supongamos que estás creando, por ejemplo, una tarjeta de restaurante. Tendría un archivo RestaurantCard.stories.tsx, que representa el componente con propiedades simuladas para cada escenario.Es importante tener en cuenta que Storybook no produce ningún código de producción. Tus archivos .stories.tsx se utilizan únicamente con fines de desarrollo.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoren

Redux explicado de manera simple y sucinta para los desarrolladores de React

2022-08-10
reactreduxjavascript

Redux es una biblioteca de administración de estado ampliamente utilizada para aplicaciones React y TypeScript. Es más fácil que nunca administrar el estado en React gracias al useState React Hook, así como a la API de contexto. Sin embargo, cuando su base de código crezca mucho, necesitará una solución de administración de estado más potente y estructurada, en lugar de ad-hoc. Ahí es donde Redux puede ayudar.Redux¿Por qué necesitas Redux?Cuando trabajas con React, generalmente terminas con un estado que se usa globalmente en toda la aplicación.Uno de los enfoques para compartir el estado en todo el árbol de componentes es usar la API de contexto. A menudo, lo usamos en combinación con hooks como useReducer y useState para administrar el estado global de la aplicación.Este enfoque funciona, pero solo puede llevarte hasta cierto punto. Al final, debes inventar tus propias formas de administrar los side-effects, depurar y dividir código de administración de estado en módulos para que no se convierta en un desastre incomprensible.Una mejor idea es utilizar herramientas especializadas. Una de esas herramientas para administrar el estado de la aplicación global es Redux.Cómo funciona ReduxRedux es un marco de gestión de estado que se basa en la idea de representar el estado global de la aplicación como una función reductora.En Redux, para administrar el estado, definimos una función que acepta dos argumentos: state, para el estado anterior, y action, el objeto que describe la actualización del estado.function reducer(state = "", action: Action) { switch (action.type) { case "SET_VALUE": return action.payload; default: return state; } }Este reductor representa un valor de tipo cadena. Maneja solo un tipo de acción: SET_VALUE.Si el tipo de campo de acción recibido no es SET_VALUE, el reductor devuelve el estado sin cambios.Después de tener el reductor, creamos la store(tienda) usando el método redux createStore.const store = createStore(reducer, "Initial Value");La store proporciona un método de suscripción que nos permite suscribirnos a las actualizaciones de la store.store.subscribe(() => { const state = store.getState(); console.log(state); });Aquí, le hemos pasado un callback que registra el valor del estado en la consola.Para actualizar el estado, despachamos(dispatch) una acción:store.dispatch({ type: "SET_VALUE", payload: "New value", });Aquí pasamos un objeto que representa la acción(action). Se requiere que cada acción tenga el campo de type y opcionalmente, payload.Por lo general, en lugar de crear acciones en el lugar, las personas definen action creator functions:const setValue = (value) => ({ type: "SET_VALUE", payload: value, });Y esta es la esencia de Redux.¿Por qué no podemos usar el hook useReducer en lugar de Redux?Desde la versión 16.8, React admite Hooks. Uno de ellos, useReducer, funciona de manera muy similar a Redux.Es fácil administrar el estado de la aplicación usando una combinación de useReducer y React Context API.Entonces, ¿por qué necesitamos Redux si tenemos una herramienta nativa que también nos permite representar el estado como un reductor? Si lo ponemos a disposición en toda la aplicación mediante la API de contexto, ¿no será suficiente?Redux ofrece algunas ventajas importantes:Herramientas del navegador: pueded usar Redux DevTools para depurar tu código Redux. Est nos permite ver la lista de acciones enviadas, inspeccionar el estado e incluso viajar en el tiempo. Puede alternar en el historial de acciones y ver cómo el estado se ocupó de cada uno de ellos.Manejo de efectos secundarios: con useReducer, debes inventar tus propias formas de organizar el código que realiza las solicitudes de red. Redux proporciona la API de middleware para manejar eso. Además, existen herramientas como Redux Thunk que facilitan aún más esta tarea.Pruebas: como Redux se basa en funciones puras, es fácil de probar. Todas las pruebas se reducen a verificar la salida con las entradas dadas.Patrones y organización de código: Redux está bien estudiado y hay recetas y mejores prácticas que puede aplicar. Existe una metodología llamada Ducks que puedes usar para organizar el código Redux.Construyendo con ReduxAhora que ha visto ejemplos de lo que hace Redux y cómo funciona, está listo para usarlo en un proyecto real.Profile@khriztianmorenoHasta la próxima

Una mejor manera de crear bibliotecas de componentes React

2022-07-05
reactjavascriptweb-development

Hoy repasarémos rápidamente cuatro patrones de programación que se aplican a los componentes compartidos en React.ReactEl uso de estos permite crear una biblioteca de componentes compartidos bien estructurada. El beneficio que obtiene es que los desarrolladores de tu organización pueden reutilizar fácilmente los componentes en numerosos proyectos. Tú y tu equipo serán más eficientes.Patrones comunesEn este post, te muestro cuatro patrones de API que puede usar con todos sus componentes compartidos. Estos son:JSX children pass-throughReact fowardRef APIJSX prop-spreading cont TypeScriptOpinionated prop defaultsPatrón 1: JSX Children Pass-ThroughReact ofrece la posibilidad de componer elementos utilizando la prop children. El diseño de componentes compartidos se apoya en gran medida en este concepto.Permitir que los consumidores proporcionen el children siempre que sea posible les facilita proporcionar contenido personalizado y otros componentes. También ayuda a alinear las API de componentes con las de los elementos nativos.Supongamos que tenemos un componente Button para empezar. Ahora permitimos que nuestro componente Button represente sus children, de la siguiente manera:// File: src/Button.tsx export const Button: React.FC = ({ children }) => { return <button>{children}</button>; };La definición de React.FC ya incluye a children como una prop válida. Lo pasamos directamente al elemento de botón nativo.A continuación, un ejemplo con Storybook para proporcionar contenido al Button.// File: src/stories/Button.stories.tsx const Template: Story = (args) => ( <Button {...args}>my button component</Button> );Patrón 2: forwardRef APIMuchos componentes tienen una asignación de uno a uno a un elemento HTML. Para permitir que los consumidores accedan a ese elemento subyacente, proporcionamos una prop de referencia utilizando la API React.forwardRef().No es necesario proporcionar un red para el desarrollo diario de React, pero es útil dentro de las bibliotecas de componentes compartidos. Permite una funcionalidad avanzada, como colocar una información sobre herramientas en relación con nuestro Button con una biblioteca de posicionamiento.Nuestro componente Button proporciona un solo HTMLButtonElement (button). Le proporcionamos una referencia con forwardRef().// File: src/buttons/Button.tsx export const Button = React.forwardRef < HTMLButtonElement > (({ children }, ref) => { return <button ref={ref}>{children}</button>; }); Button.displayName = "Button";Para ayudar a los consumidores de TypeScript a entender qué elemento se devuelve desde el objeto ref, proporcionamos una variable type que representa el elemento al que lo estamos pasando, HTMLButtonElement en este caso.Patrón 3: JSX Prop-SpreadingOtro patrón que aumenta la flexibilidad de los componentes es la propagación de props. La propagación de props permite a los consumidores tratar nuestros componentes compartidos como reemplazos directos para sus contrapartes nativas durante el desarrollo.La propagación de props ayuda con los siguientes escenarios:Proporcionar props accesibles para cierto contenido.Agrega atributos de datos personalizados para pruebas automatizadasUtiliza un evento nativo que no esta definido en nuestras props.Sin propagación de props, cada uno de los escenarios anteriores requeriría que se definieran atributos explícitos. La propagación de props ayuda a garantizar que nuestros componentes compartidos permanezcan tan flexibles como los elementos nativos que utilizan internamente.Agreguemos propagación de props a nuestro componente Botón.// File: src/buttons/Button.tsx export const Button = React.forwardRef< HTMLButtonElement, React .ComponentPropsWithoutRef<'button'> >(({ children, ...props }, ref) => { return ( <button ref={ref} {...props}> {children} </button> ); });Podemos hacer referencia a nuestras props restantes con la sintaxis de propagación y aplicarlos al botón. React.ComponentPropsWithoutRef es una utilidad de tipos que ayuda a documentar los props válidos para un elemento de botón para nuestros consumidores de TypeScript.Algunos ejemplos de esta verificación de tipos en acción:// Pass - e is typed as // `React.MouseEventMouseEvent>` <Button onClick={(e) => { console.log(e) }} /> // Pass - aria-label is typed // as `string | undefined` <Button aria-label="My button" /> // Fail - type "input" is not // assignable to `"button" | // "submit" | "reset" | undefined` <Button type="input" />Patrón 4: Valores predeterminados con opinionesPara ciertos componentes, es posible que desee asignar atributos predeterminados a valores específicos. Ya sea para reducir errores o mejorar la experiencia del desarrollador, proporcionar un conjunto de valores predeterminados es específico para una organización o equipo. Si encuentra la necesidad de predeterminar ciertas props, debe asegurarse de que aún sea posible para los consumidores anular esos valores si es necesario.Una complejidad común que se encuentra con los elementos button es el tipo de valor predeterminado, "submit". Este tipo predeterminado a menudo envía formularios circundantes accidentalmente y conduce a escenarios de depuración difíciles. A continuación, le mostramos cómo establecemos el atributo "button" de forma predeterminada.Actualicemos el componente Button para devolver un botón con el tipo actualizado.// File: src/buttons/Button.tsx return ( <button ref={ref} type="button" {...props}> {children} </button> );Al colocar las props predeterminadas antes de la difusión de props, nos aseguramos de que cualquier valor proporcionado por los consumidores tenga prioridad.Mira algunas bibliotecas de código abiertoSi está creando una biblioteca de componentes para tu equipo, eche un vistazo a las bibliotecas de componentes de código abierto más populares para ver cómo utilizan los patrones anteriores. Aquí hay una lista de algunas de las principales bibliotecas de componentes de React de código abierto para examinar:Ant DesignRainbow UIGrommetProfile@khriztianmorenoHasta la próxima

NPM dependencies vs devDependencies

2022-06-20
javascriptweb-developmentnpm

tl;drLas dependencies son requeridas por nuestra aplicación en tiempo de ejecución. Paquetes como react, redux y lodash son todos ejemplos de dependencias. Las devDependencies solo son necesarias para desarrollar o compilar su aplicación. Paquetes como babel, enzyme y prettier son ejemplos de devDependencies.NPM dependencies vs devDependenciesnpm installLa diferencia real entre dependencies y devDependencies se ve cuando ejecuta npm install.Si ejecuta npm install desde un directorio que contiene un archivo package.json (lo que normalmente hace después de clonar un proyecto, por ejemplo).✅ Se instalarán todos los paquetes ubicados en dependencies ✅ Se instalarán todos los paquetes ubicados en devDependenciesSi ejecuta npm install <package-name> (lo que normalmente hace cuando desea agregar un nuevo paquete aL proyecto existente), es decir, npm install react.✅ Se instalarán todos los paquetes ubicados en dependencies ❌ No se instalará ninguno de los paquetes ubicados en devDependenciesDependencias transitivasSi el paquete A depende del paquete B y el paquete B depende de C, entonces el paquete C es una dependencia transitiva del paquete A. Lo que eso significa es que para que el paquete A se ejecute correctamente, necesita el paquete B instalado. Sin embargo, para que el paquete B se ejecute correctamente, es necesario que esté instalado el paquete C. ¿Por qué menciono esto? Bueno, las dependencies y devDependencies también tratan las dependencias transitivas de manera diferente.Cuando ejecutas npm install desde un directorio que contiene un archivo package.json:dependencies ✅ Descarga todas las dependencias transitivas.devDependencies ❌ No descarga ninguna dependencia transitiva.Especificar dependencies frente a devDependenciesA partir de NPM 5, cuando ejecuta npm install <package-name>, ese paquete se guardará automáticamente dentro de sus dependencies en su archivo package.json. Si quisiera especificar que el paquete específico debería incluirse en devDependencies en su lugar, agregaría la marca --save-dev.npm install prettier --save-devInstalación en un servidor de producciónA menudo, necesitará instalar su proyecto en un servidor de producción. Cuando haga eso, no querrá instalar devDependencies ya que obviamente no las necesitará en su servidor de producción. Para instalar solo las dependencies (y no devDependencies), puede usar la marca --production.npm install --production¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoren

Un manual práctico sobre los sistemas de módulos de JavaScript

2022-06-12
javascriptweb-development

Hoy te daré una introducción práctica sobre los sistemas de módulos que usamos cuando construimos bibliotecas en JavaScript. A medida que una aplicación web o biblioteca crece y se agregan más funciones, la modularización del código mejora la legibilidad y el mantenimiento. Esta guía rápida le dará una visión incisiva de las opciones disponibles para crear y consumir módulos en JavaScript.JavaScript Module SystemsSi alguna vez se ha preguntado cuáles son los pros y los contras de AMD, ESM o CommonJS, esta guía le brindará la información que necesita para elegir con confianza entre todas las opciones.Una historia de módulos de JavaScriptSin funciones nativas integradas para espacios de nombres y módulos en las primeras versiones del lenguaje JavaScript, se han introducido diferentes formatos de módulo a lo largo de los años para llenar este vacío.Los más notables, que le mostraré cómo usar en su código JavaScript a continuación, son:Expresión de función inmediatamente invocada (IIFE)CommonJS (CJS)Definición de módulo asíncrono (AMD)Definición de módulo universal (UMD)Módulos ECMAScript (ESM)La selección de un sistema de módulos es importante al desarrollar una biblioteca de JavaScript. Para los autores de bibliotecas, la elección del sistema de módulos para su biblioteca afecta la adopción por parte del usuario y la facilidad de uso. Querrá estar familiarizado con todas las posibilidades.1. Expresión de función inmediatamente invocada (IIFE) - Immediately Invoked Function ExpressionUna de las primeras formas de exponer bibliotecas en el navegador web, las expresiones de función invocadas inmediatamente (IIFE) son funciones anónimas que se ejecutan inmediatamente después de ser definidas.(function () { // Module's Implementation Code })();Un patrón de diseño común que aprovecha los IIFE es el patrón Singleton, que crea una única instancia de objeto y código de espacios de nombres. Este objeto sirve como un único punto de acceso a un grupo específico de funciones. Para ver ejemplos del mundo real, no busque más allá del objeto Math o la biblioteca jQuery.ProsEscribir módulos de esta manera es conveniente y compatible con navegadores más antiguos. De hecho, puede concatenar y agrupar de forma segura varios archivos que contienen IIFE sin preocuparse por las colisiones de nomenclatura y alcance.ContrasSin embargo, los módulos IIFE se cargan sincrónicamente, lo que significa que ordenar correctamente los archivos del módulo es fundamental. De lo contrario, la aplicación se romperá. Para proyectos grandes, los módulos IIFE pueden ser difíciles de administrar, especialmente si tiene muchas dependencias superpuestas y anidadas.2. CommonJS (CJS)El sistema de módulos predeterminado de Node.js, CommonJS (CJS) usa la sintaxis require para importar módulos y la sintaxismodule.exports y export para exportaciones predeterminadas y con nombre, respectivamente. Cada archivo representa un módulo y todas las variables locales del módulo son privadas, ya que Node.js envuelve el módulo dentro de un contenedor de funciones.Por ejemplo, este módulo ..const { PI, pow } = Math; function calculateArea(radius) { return PI * pow(radius, 2); } module.exports = calculateArea;Se convierte en ...(function (exports, require, module, __filename, __dirname) { const { PI, pow } = Math; function calculateArea(radius) { return PI * pow(radius, 2); } module.exports = calculateArea; });El módulo no solo tiene sus variables dentro del ámbito privado, sino que aún tiene acceso global a, exports, require y module. __filename y __dirname tienen el ámbito del módulo y contienen el nombre del archivo y el nombre del directorio del módulo, respectivamente.La sintaxis requerida le permite importar módulos incorporados de Node.js o módulos de terceros instalados localmenteProsLas sentencias require de CommonJS son síncronas, lo que significa que los módulos de CommonJS se cargan de forma síncrona. Siempre que sea el único punto de entrada de la aplicación, CommonJS automáticamente sabe cómo ordenar los módulos y manejar las dependencias circulares.ContrasAl igual que los IIFE, CommonJS no se diseñó para generar paquetes de tamaño pequeño. El tamaño del paquete no se tuvo en cuenta en el diseño de CommonJS, ya que CommonJS se utiliza principalmente para desarrollar aplicaciones del lado del servidor. Para las aplicaciones del lado del cliente, el código debe descargarse primero antes de ejecutarlo. La falta de agitación de árboles convierte a CommonJS en un sistema de módulos no óptimo para aplicaciones del lado del cliente.3. Definición de módulo asíncrono (AMD) - Asynchronous Module DefinitionA diferencia de IIFE y CommonJS, Asynchronous Module Definition (AMD) carga módulos y sus dependencias de forma asincrónica. Con origen en Dojo Toolkit, AMD está diseñado para aplicaciones del lado del cliente y no requiere herramientas adicionales. De hecho, todo lo que necesita para ejecutar aplicaciones siguiendo el formato del módulo AMD es la biblioteca RequireJS, un cargador de módulos en el navegador. Eso es. Aquí hay un ejemplo simple que ejecuta una aplicación React simple, estructurada con AMD, en el navegador.<!-- index.html --> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>React + AMD</title> </head> <body> <div id="root"></div> <script type="text/javascript" src="https://cdnjs.cloudflare.com /ajax/libs/require.js/2.3.6 /require.min.js" ></script> <script type="text/javascript" src="main.js"></script> </body> </html>A continuación, este es el aspecto de JavaScript.// main.js requirejs.config({ paths: { react: "https://unpkg.com/react@15.3.2 /dist/react", "react-dom": "https://unpkg.com /react-dom@15.3.2 /dist/react-dom", }, }); requirejs( ["react", "react-dom"], (React, ReactDOM) => { ReactDOM.render( React.createElement( "p", {}, "Greetings!" ), document.getElementById("root") ); } );Llamar a los métodos requirejs o define registra la función de fábrica (la función anónima pasada como segundo argumento a estos métodos). AMD ejecuta esta función solo después de que se hayan cargado y ejecutado todas las dependencias.ProsAMD permite definir varios módulos dentro de un solo archivo y es compatible con navegadores más antiguos.ContrasAMD no es tan popular como los formatos de módulos más modernos, como los módulos ECMAScript y la definición de módulo universal.4. Definición de módulo universal (UMD) - Universal Module DefinitionPara las bibliotecas que admiten entornos del lado del cliente y del lado del servidor, la Definición de módulo universal (UMD) ofrece una solución unificada para hacer que los módulos sean compatibles con muchos formatos de módulo diferentes, como CommonJS y AMD.Aquí está UMD en acción desde la biblioteca de desarrollo de React(function (root, factory) { if (typeof define === "function" && define.amd) { // Checks for RequireJS's // `define` function. // Register as an anonymous module. define(["exports"], factory); } else if ( typeof exports === "object" && typeof exports.nodeName !== "string" ) { // Checks for CommonJS. // Calls the module factory // immediately. factory(exports); } else { // Register browser globals. global = root || self; factory((global.React = {})); } })(this, function (exports) { "use strict"; // Place React's module code here. // ... });Si el IIFE detecta una función de definición en el alcance global y una propiedad amd en la definición, entonces ejecuta el módulo como un módulo AMD.Si el IIFE detecta un objeto de exportación en el ámbito global y una propiedad nodeName dentro de las exportaciones, entonces ejecuta el módulo como un módulo CommonJS.ProsIndependientemente de si una aplicación consume su biblioteca como un módulo CommonJS, AMD o IIFE, UMD verifica condicionalmente el formato del módulo que se está utilizando en tiempo de ejecución y ejecuta código específico para el formato del módulo detectado.ContrasEl código de la plantilla UMD es un IIFE de aspecto intimidante y su uso es inicialmente un desafío. Sin embargo, UMD en sí no es conceptualmente complicado.5. Módulos ECMAScript (ESM)Los módulos ECMAScript (ESM), el formato de módulo introducido más recientemente, es la forma estándar y oficial de manejar módulos en JavaScript. Este formato de módulo se usa comúnmente en aplicaciones TypeScript.Al igual que CommonJS, ESM proporciona varias formas de exportar código: exportaciones predeterminadas o exportaciones con nombre.// circle.js export function calculateArea() { return Math.PI * Math.pow(radius, 2); } export function calculateCircumference() { return 2 * Math.PI * radius; }La importación de estas exportaciones nombradas por separado le dice al paquete de módulos qué partes del módulo importado deben incluirse en el código generado. Se omiten todas las exportaciones con nombre no importadas. Esto reduce el tamaño de la biblioteca, lo cual es útil si su biblioteca se basa en algunos métodos de una biblioteca de utilidades grande como lodash.Ahora, en algún archivo en el mismo directorio que ./circle.js, necesitaríamos el módulo de la siguiente manera.const { calculateArea, calculateCircumference } = require("./circle"); console.log(calculateArea(5)); console.log(calculateCircumference(5));ProsLos paquetes de módulos son compatibles con ESM y optimizan el código mediante técnicas como la agitación de árboles (elimina el código no utilizado del resultado final), que no son compatibles con otros formatos de módulo. La carga y análisis de módulos es asincrónica, pero su ejecución es sincrónica.ContrasEste es el sistema de módulos principales más nuevo. Como tal, algunas bibliotecas aún no lo han adoptado.Creación de tu propia biblioteca de React/JavaScriptComo puede imaginar, elegir el sistema de módulos correcto se vuelve importante al crear tu propia biblioteca React. Personalmente con el uso hoy en dia de herramientas como babel.js podriamos trabajar con modulos de ECMAScript, pero yo soy partidario de usar CommonJS en Node y ECMAScript Modules (ESM) en el frontend.Profile@khriztianmoren

Introducción a Volta, la forma más rápida de administrar entornos de Node

2022-05-27
javascriptweb-developmentprogramming

Volta, es una herramienta que abre las posibilidades para una experiencia de desarrollo más fluida con Node.js. Esto es especialmente relevante para trabajar en equipo. Volta te permite automatizar tu entorno de desarrollo Node.js. Permite a tu equipo usar las mismas versiones consistentes de Node y otras dependencias. Aún mejor, permite mantener las versiones consistentes en los entornos de producción y desarrollo, eliminando los errores sutiles que vienen con los desajustes de versiones.Volta elimina los problemas de "Funciona en mi máquina ..."Los desajustes de versiones causan dolores de cabeza cuando se desarrolla en equipo.Supongamos este escenario:El equipo X creó su aplicación en máquinas locales que ejecutaban Node 10, pero la canalización de compilación adoptó de forma predeterminada la versión de Node más baja que tenía a mano, Node 6, y la aplicación no se iniciaba en producción. Tuvieron que revertir el despliegue, averiguar qué salió mal, se convirtió en una noche muy larga.Si hubieran usado Volta esto pudo haberse evitado.Como trabaja Volta?Volta es "una forma sencilla de administrar sus herramientas de línea de comandos de JavaScript". Hace que la administración de Node, npm, yarn u otros ejecutables de JavaScript enviados como parte de los paquetes, sea realmente fácil.Volta tiene mucho en común con herramientas como NVM, pero NVM no es la más fácil de configurar inicialmente y, lo que es más importante, el desarrollador que lo usa todavía tiene que recordar cambiar a la versión correcta de Node para el proyecto en el que están trabajando.Volta, por otro lado, es fácil de instalar y elimina la parte pensante de la ecuación: una vez que Volta esté configurado en un proyecto e instalado en una máquina local, cambiará automáticamente a las versiones adecuadas de Node.No solo eso, sino que también le permitirá definir versiones de yarn y npm en un proyecto, y si la versión de Node definida en un proyecto no se descarga localmente, Volta saldrá y descargará la versión apropiada.Pero cuando cambia a otro proyecto, Volta cederá a los ajustes preestablecidos en ese proyecto o volverá a las variables de entorno predeterminadas.Volta en acciónDemos a Volta a dar una vuelta. Primero, cree una nueva aplicación React con Create React App.Ejecute el siguiente comando desde una terminal.npx create-react-app volta-sample-appUna vez que haya creado su nueva aplicación React, abra el código en un IDE e inícielo a través de la línea de comando.npm run startSi todo va según el plan, verá un logotipo de React giratorio cuando abra un navegador en http://localhost:3000/Ahora que tenemos una aplicación, agreguemos Volta.Descarga Volta localmentePara instalar Volta, ejecute el siguiente comando:curl https://get.volta.sh | shellSi tiene Windows, descargue y ejecute el instalador de Windows y siga las instrucciones.Defina sus variables de entornoAntes de agregar nuestras versiones de Node y npm específicas de Volta a nuestro proyecto, veamos cuáles son las variables de entorno predeterminadas.Obtenga una lectura de referenciaEn una terminal en la raíz de su proyecto, ejecute el siguiente comando.node -v && npm -vPara mí, mis versiones predeterminadas de Node y npm son v14.18.1 y v6.14.15, respectivamente.Con nuestra línea de base establecida, podemos cambiar nuestras versiones solo para este proyecto con la ayuda de Volta.Fijar una version de node.jsEmpezaremos con Node. Dado que v16 es la versión actual de Node, agreguemos eso a nuestro proyecto.En nuestro proyecto en el nivel raíz donde vive nuestro archivo package.json, ejecute el siguiente comando.volta pin node@16El uso de volta pin [JS_TOOL]@[VERSION] pondrá esta herramienta JavaScript en particular en nuestra versión especificada en el package.json de nuestra aplicación. Después de enviar esto a nuestro repositorio con git, cualquier desarrollador futuro que use Volta para administrar dependencias podrá leer esto del repositorio y usar exactamente la misma versión.Con Volta podemos ser tan específicos o genéricos como deseamos definir las versiones, y Volta llenará cualquier vacío. Especifiqué la versión principal de Node que quería (16) y luego Volta completó las versiones menores y de parche por mí.Después de anclar, verá el siguiente mensaje de éxito en su terminal: pinned node@16.11.1 in package.json.Consejo: haga que su versión de node anclada coincida con la versión de Node de su servidor de compilaciónFijar una version de npmAhora abordemos nuestra versión npm. Aún en la raíz de nuestro proyecto en la terminal, ejecute este comando:volta pin npmSin una versión especificada, Volta elige por defecto la última versión de LTS para agregar a nuestro proyecto.La versión actual de LTS para npm es 8, por lo que ahora nuestro proyecto tiene npm v8.1.0 como su versión predeterminada.Verificar el package.jsonPara confirmar que las nuevas versiones del entorno de JavaScript son parte de nuestro proyecto, verifique el archivo package.json de la aplicación.Desplácese hacia abajo y debería ver una nueva propiedad llamada "volta". Dentro de la propiedad "volta" debe haber un "node": "16.11.1" y una versión "npm": "8.1.0"A partir de ahora, cualquier desarrollador que tenga Volta instalado en su máquina y baje este repositorio tendrá la configuración de estas herramientas para cambiar automáticamente para usar estas versiones particulares de node y npm.Para estar doblemente seguro, también puede volver a ejecutar el primer comando que hicimos antes de anclar nuestras versiones con Volta para ver cómo está configurado nuestro entorno de desarrollo actual.node -v && npm -vDespués de esto, su terminal debería decirle que está usando esas mismas versiones: Node.js v16 y npm v8.Mira cómo sucede la magiaAhora, puedes sentarte y dejar que Volta se encargue de las cosas por ti.Si deseas ver qué sucede cuando no hay nada especificado para Volta, intente subir un nivel desde la raíz de su proyecto y verifique sus versiones de Node y npm nuevamente.Abramos dos terminales una al lado de la otra: la primera dentro de nuestro proyecto con versiones de Volta, la otra un nivel más alto en nuestra estructura de carpetas.Ahora ejecute el siguiente comando en ambos:node -v && npm -vY en nuestro proyecto, Node v16 y npm v8 se están ejecutando, pero fuera del proyecto, Node v14 y npm v6 están presentes. No hicimos nada más que cambiar de directorio y Volta se encargó del resto.Al usar Volta, eliminamos las conjeturas de nuestras variables de entorno de JavaScript y, de hecho, dificultamos que un miembro del equipo de desarrollo use las versiones incorrectas que las correctas.Profile@khriztianmoren

Testing framework - Node.js

2020-04-17
javascripttestingnodejs

Una vez que una aplicación se está ejecutando en producción, puede darnos miedo hacer cambios. ¿Cómo sabemos que una nueo feature, un fix o un refactor no romperá la funcionalidad existente?Podemos usar nuestra aplicación manualmente para tratar de encontrar errores, pero sin mantener una lista de verificación exhaustiva, es poco probable que cubramos todos los posibles puntos de falla. Y, sinceramente, incluso si lo hiciéramos, llevaría demasiado tiempo ejecutar nuestra aplicación completa después de cada commit.Al usar un framework de testing, podemos escribir código que verifique que nuestro código anterior aún funciona. Esto nos permite realizar cambios sin temor a romper la funcionalidad esperada.Pero hay muchos frameworks de testing diferentes, puede ser difícil saber cuál usar. A continuación, voy a hablar sobre tres de ellos para Node.js:TapeAvaJestTAPEEste deriva su nombre de su capacidad para proporcionar resultados estructurados a través de TAP (Test Anything Protocol). La salida de nuestro runner es amigable para los humanos, pero otros programas y aplicaciones no la pueden analizar fácilmente. El uso de un protocolo estándar permite una mejor interoperabilidad con otros sistemas.Además, Tape tiene varios métodos de conveniencia que nos permiten omitir y aislar pruebas específicas, así como verificar expectativas adicionales como errores, deep equality y throwing.En general, la ventaja de Tape es su simplicidad y velocidad. Es un arnés sólido y sencillo que hace el trabajo sin una curva de aprendizaje empinada.Así es como se ve una prueba básica con tape:const test = require("tape"); test("timing test", (t) => { t.plan(2); t.equal(typeof Date.now, "function"); const start = Date.now(); setTimeout(function () { t.equal(Date.now() - start, 100); }, 100); });Y si lo ejecutamos, se ve así:$ node example/timing.js TAP version 13 # timing test ok 1 should be strictly equal not ok 2 should be strictly equal --- operator: equal expected: 100 actual: 107 ... 1..2 # tests 2 # pass 1 # fail 1El método test() espera dos argumentos: el nombre de la prueba y la función de prueba. La función de prueba tiene el objeto t como argumento, y este objeto tiene métodos que podemos usar para aserciones: t.ok(), t.notOk(), t.equal() y t.deepEqual() solo para nombrar un pocos.AVAAVA tiene una API concisa, salida de error detallada, abarca nuevas características de lenguaje y tiene aislamiento de proceso para ejecutar pruebas en paralelo. AVA está inspirado en la sintaxis de Tape y admite la generación de informes a través de TAP, pero se desarrolló para ser más obstinado, proporcionar más funciones y poder ejecutar pruebas al mismo tiempo.AVA solo ejecutará pruebas ava binary. Con Tape podríamos ejecutar node my-tape-test.js, pero con AVA primero debemos asegurarnos de que: AVA esté instalado globalmente y disponible en la línea de comandos (por ejemplo, npm i -g ava).Además, AVA es exigente acerca de cómo se nombran los archivos de prueba y no se ejecutará a menos que el archivo termine con "test.js".Una cosa que debe saber sobre AVA es que por defecto ejecuta pruebas en paralelo. Esto puede acelerar muchas pruebas, pero no es ideal en todas las situaciones. Cuando las pruebas que leen y escriben en la base de datos se ejecutan simultáneamente, pueden afectarse entre sí.AVA también tiene algunas funciones útiles de ayuda que facilitan la configuración y el desmontaje: métodos test.before() y test.after() para la configuración y limpieza.AVA también tiene métodos test.beforeEach() y test.afterEach() que se ejecutan antes o después de cada prueba. Si tuviéramos que agregar más pruebas de base de datos, podríamos borrar nuestra base de datos aquí en lugar de pruebas individuales.Así es como se ve una prueba de AVA:const test = require("ava"); test("foo", (t) => { t.pass(); }); test("bar", async (t) => { const bar = Promise.resolve("bar"); t.is(await bar, "bar"); });Al iterar en las pruebas, puede ser útil ejecutar AVA en "watch mode". Esto observará tus archivos en busca de cambios y volverá a ejecutar automáticamente las pruebas. Esto funciona particularmente bien cuando creamos primero una prueba fallida. Podemos concentrarnos en agregar funcionalidad sin tener que seguir cambiando para reiniciar las pruebas.AVA es muy popular y es fácil ver por qué. AVA es una excelente opción si estamos buscando algo que nos facilite la ejecución simultánea de pruebas, proporcione helpers como before() y afterEach() y proporcione un mejor rendimiento por defecto, todo mientras mantiene una API concisa y fácil de entender.JestEs un framework de pruebas que ha aumentado en popularidad junto con React.js. La documentación de React lo enumeran como la forma recomendada de probar React, ya que permite usar jsdom para simular fácilmente un entorno de navegador. También proporciona funciones para ayudar a simular módulos y temporizadores.Aunque Jest es muy popular, se usa principalmente para pruebas de front-end. Utiliza Node.js para ejecutarse, por lo que es capaz de probar tanto el código basado en el navegador como las aplicaciones y módulos de Node.js. Sin embargo, tenga en cuenta que el uso de Jest para probar las aplicaciones del lado del servidor Node.js viene con advertencias y configuración adicional.En general, Jest tiene muchas funcionalidades que pueden ser atractivas. Aquí hay algunas diferencias clave de Tape y AVA:Jest no se comporta como un módulo Node.js normal.El archivo de prueba debe ejecutarse con jest, y varias funciones se agregan automáticamente al alcance global (por ejemplo, describe(), test(), beforeAll() y expect()). Esto hace que los archivos de prueba sean "especiales" ya que no siguen la convención de Node.js de usar require() para cargar la funcionalidad de jest. Esto causará problemas con linters como standard que restringen el uso de globales indefinidos.Jest utiliza su expect() global para realizar comprobaciones, en lugar de afirmaciones estándar. Jest espera que se lea más como inglés. Por ejemplo, en lugar de hacer algo como t.equal(actual, expected, comment) con tape y AVA, usamos expect(actual).toBe(expected). Jest también tiene modificadores inteligentes que puede incluir en la cadena como .not() (por ejemplo, expect(actual).not.toBe(unexpected)).Jest tiene la capacidad de mockear funciones y módulos. Esto puede ser útil en situaciones en las que es difícil escribir o cambiar el código que estamos probando para evitar resultados lentos o impredecibles en un entorno de prueba. Un ejemplo en la documentación de Jest es evitar que axios realice una solicitud HTTP real a un servidor externo y, en su lugar, devolver una respuesta preconfigurada.Jest tiene una API mucho más grande y con muchas más opciones de configuración. Algunos de ellos no funcionan bien cuando se realizan pruebas para Node.js. La opción más importante que debemos establecer es que testEnvironment debe ser "node". Si no hacemos esto, jest usa la configuración predeterminada en la que nuestras pruebas se ejecutarán en un entorno similar a un navegador usando jsdom.Así es como se ve una prueba de Jest:const sum = require("./sum"); test("adds 1 + 2 to equal 3", () => { expect(sum(1, 2)).toBe(3); });Jest tiene una API mucho más grande y ofrece más funcionalidad que AVA o tape. Sin embargo, el mayor alcance no está exento de inconvenientes. Al usar Jest para probar el código Node.js, tenemos que:Estar de acuerdo con el uso de globales indefinidos.No usar funciones como temporizadores simulados que interfieren con paquetes como Mongoose.Debemos configurar el entorno correctamente para que no se ejecute en un navegador simulado de forma predeterminada.Considere que cierto código puede correr 20-30 veces más lento en Jest en comparación con otros test runners.Muchos equipos elegirán Jest porque ya lo están utilizando en el front-end y no les gusta la idea de tener múltiples test runners, o les gustan las características integradas como mocks y no quieren incorporar módulos adicionales. En última instancia, estas compensaciones deben realizarse caso por caso.Otras herramientas de pruebaHay un montón de otras herramientas de prueba como Istanbul, nyc, nock y replay que no tenemos espacio para entrar aquí.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

JAMstack. Y cómo los sitios web son cada vez más rápidos

2020-03-20
javascriptapihtmljamstack

Si estás involucrado en el mundo de los sitios web, es probable que hayas oído hablar de JAMstack.JAMstack significa:JavaScriptAPI’sMarkupEl JAMstack ha inspirado algunas de las mejores herramientas de desarrollo web que hemos visto. Publicar sitios web increíblemente rápidos, seguros y accesibles nunca ha sido tan fácil ni tan gratuito. Todavía me cuesta trabajo creer que mi propio sitio web personal ahora se ejecuta de forma gratuita en lugar de un VPS de $15/mes.Veamos un corto repaso por varias etapas de la historia de la web hasta llegar al día de hoy y ver esa evolución a donde nos ha llevado.Cuando surgió la webEn los años 90, las páginas web no se veían tan espectaculares. HTML se utilizó inicialmente para almacenar documentos y enviarlos a través de la World Wide Web. Se veían exactamente como lo haría un documento de Word.Teniendo en cuenta el tiempo, esto era un BUM!!. Esto fue algo revolucionario e incluso, los sitios web como Wikipedia comparten actualmente este aspecto “mínimo” como si lo estuvieras leyendo en un papel.A medida que la web crecía, los desarrolladores querían tener más control sobre cómo hacer que se vieran sus documentos. CSS se propuso el 10 de octubre de 1994 y se lanzó en 1996. No se detectó tan rápido ya que Internet Explorer 3 tenía soporte limitado para él. De cualquier manera, la web estaba evolucionando y también lo eran las herramientas detrás de ella. Algunas gemas todavía se pueden ver en línea ahora que se hicieron con tecnologías tan antiguas, pero aún así tuvieron excelentes actuaciones y permitieron una gran interfaz de usuario.Después de que se introdujera JavaScript en la WWW, se usó JavaScript para hacer que la web fuera mucho más dinámica y la Web creció, también lo hicieron las empresas que operaban en Internet. Con la evolución de la web, había muchas formas de probar y vender productos e información. Dado que una gran cantidad de código es Open Source, muchos desarrolladores lanzaron librerias de JavaScript que ayudaron a mejorar la web.Generadores de sitio estáticoLos generadores de sitios estáticos son muy populares en 2018. La gente dice que son una tendencia que los desarrolladores web deben tener en cuenta este año que finaliza y es comprensible. Para la mayoría de los casos, es la solución correcta y lo hace bien. Aquí hay un par de generadores de sitios estáticos muy populares en una comparación.Hugo vs JekyllHugo vs JekyllHugo y Jekyll son excelentes maneras de comenzar con los generadores de sitios estáticos. Mucha gente los usa como sus métodos principales de blogging y administración de páginas.La web moderna¿Cuántas veces has escuchado las palabras “La web moderna” y solo has asumido una connotación negativa hacia ella? No te preocupes, no estoy aquí para hablar mal de la web. En todo caso, lo adoro. Las aplicaciones web de hoy en día se centran más en crear grandes experiencias utilizando bibliotecas de JavaScript más robustas y API RESTful para hacer las cosas mucho más fáciles y rápidas. Por eso me encanta React/Vue porque hace que la web sea un lugar mucho más rápido y accesible.JAM StackQue es donde estamos ahora.❤❤GatsbyJS es un recién llegado al mundo de JavaScript y los generadores de sitios estáticos. Utiliza tecnologías modernas como **GraphQL** y **React** para crear sitios web extremadamente rápidos. Puede usarlo con cualquier CMS que tenga una API RESTful (Wordpress, Contentful, Netlify CMS, Stripe, storyblok, etc). Gatsby es muy poderoso y ha tenido un gran éxito en la comunidad Open Source y en Venture Capital.Si eres de Medellín, Colombia y estas interesado en aprender sobre #GatsbyJS, puedes votar en el siguiente tweet o dejar un comentario en el mismo, para conocer el interes de las personas por esta tecnología y quizas podamos hacer material para compartir es este blog.<blockquote class="twitter-tweet"><p lang="es" dir="ltr">How many of you would be interested in having talks, workshops, <a href="https://twitter.com/GatsbyJS?ref_src=twsrc%5Etfw">@gatsbyjs</a> events in the city of Medellin? 👨🏻‍💻♥️👨🏻‍🏫<br><br>Cuantos de ustedes, estarían interesados en tener charlas, talleres, eventos de <a href="https://twitter.com/hashtag/gatsbyjs?src=hash&amp;ref_src=twsrc%5Etfw">#gatsbyjs</a> en la ciudad de medellin?👨‍💻♥️🙌🏻</p>&mdash; Khriztian Moreno 👨🏼‍💻👨🏼‍🏫 (@khriztianmoreno) <a href="https://twitter.com/khriztianmoreno/status/1067593264814088192?ref_src=twsrc%5Etfw">November 28, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>El futuro de la webMucha gente ha estado prediciendo que el futuro de la web será un mundo inmersivo en el que podamos ingresar a un área similar a Matrix. Para mí, lo que me imagino es que la web será accesible para todos los que pueden tener una computadora de mala calidad o no tener acceso a Internet extremadamente rápido y gracias a herramientas como **#GatsbyJS **podremos lograr este sueño.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!*PD: Dependiendo de las respuesta a mi tweet, veremos si creamos mas material acerca de JAMstack y GatsbyJS*¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

HEADLESS CMS  —  La mejor solución para el desarrollo con contenidos

2020-03-10
javascriptheadless-cmsweb-development

A medida que el mundo se vuelve más conectado, un número cada vez mayor de empresas recurren a los sistemas de gestión de contenido para interactuar mejor con su base de clientes. Todos hemos oído hablar de WordPress, Drupal, Joomla, Sitecore y Squarespace. Sin embargo, muchas de estas herramientas tradicionales de CMS no parecen estar al día con la rápida evolución de la tecnología.Su implementación y mantenimiento cuestan mucho y pueden presentar una gran cantidad de riesgos de seguridad. Tampoco son muy flexibles, están atascados por capas de múltiples plantillas y restricciones de marco que pueden dificultar la introducción de la funcionalidad móvil.Pero hay una solución simple: go headless (ir sin cabeza).Integrar con cualquier base de códigoUn concepto relativamente nuevo, un Headless CMS esencialmente elimina la interfaz de la ecuación, permitiendo a los desarrolladores integrarse con cualquier base de código. La atención se centra en la API y la tecnología backend utilizada para almacenar y entregar contenido a cualquier dispositivo o sitio web.Las mismas capacidades de edición todavía están disponibles para los usuarios, pero sin todos los puntos de vista y respuestas que gobiernan muchos de los enfoques de CMS tradicionales.Los Headless CMS nos brindan mucha libertad sobre cómo implementar el contenido en sí. Podemos tener un control total sobre el aspecto del producto final, y no se pierde tiempo valioso construyendo plantillas desde cero.Un CMS tradicional requiere mucho tiempo, mientras que un Headless CMS es relativamente fácil de entregar, ya que los desarrolladores generalmente encuentran plantillas prefabricadas que son adecuadas para muchas variaciones de un producto en línea.Cuando hablamos de varias aplicaciones que consumen la misma API, tiene sentido extraerlas y colocarlas en una API real, esto ayuda a mantener todo el proceso de cada aplicación y asegurarse de que tengan los mismos datos.Cuando ir por un Headless CMS¿Hay un momento en que un CMS tradicional sería mejor que ir por Headless?Como en toda respuesta relacionada con software, depende del producto, aunque una mejor pregunta es si necesito o no un CMS completo.Muchos clientes suelen querer hacer algún tipo de CMS, especialmente para landing pages, lo que requiere tiempo y dinero. Sin embargo, si solo se planea cambiar el contenido de su sitio una o dos veces al año, ¿realmente necesita un CMS? Probablemente no.Si, por otro lado, tiene contenido que está cambiando constantemente, como un sitio web de noticias, entonces su mejor solución sería un enfoque headless.¿Cuáles son los beneficios de un Headless CMS? ¿Es un enfoque tradicional mejor para nuestros proyectos? ¿Y es que invertir más dinero y tiempo en una solución personalizada es mejor estrategia?Abordaremos unpoco más en una próxima publicación del blog sobre los beneficios de Headless CMS. Mientras tanto, puede obtener más información sobre Headless CMS en https://headlesscms.org y https://jamstack.org.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

Design Systems con ReactJS y Storybook

2020-03-05
javascriptreactstorybookdesign-system

Documentar y probar tus componentes de React de forma aislada utilizando Storybook.Storybook ReactStorybook Reacttl;dr: En esta entrada, aprenderemos cómo configurar toda la infraestructura necesaria para construir un sistema de diseño de componentes reutilizables en React, utilizando Storybook.*Comencemos por entender que un sistema de diseño es una serie de componentes que se pueden reutilizar en diferentes combinaciones. Los sistemas de diseño te permiten gestionar el diseño. Si vamos a a designsystemsrepo.com podrá ver los sistemas de diseño utilizados por algunas de las compañías más grandes y las marcas más sólidas, como Priceline, Apple, IBM, WeWork, GitHub e incluso el gobierno de los EE. UU.Los sistemas de diseño pueden ser un importante multiplicador de la productividad en cualquier proyecto o empresa de tamaño mediano a grande, ya que podemos documentar nuestros componentes a medida que los desarrollamos, garantizando una apariencia y sensación coherente en todas las pantallas, y teniendo un flujo de trabajo continuo entre diseñadores y desarrolladores.<iframe width="100%" height="315" src="https://www.youtube.com/embed/guteTaeLoys?si=_8X6KwUOZCjQvwan" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>A lo largo de este video, construiremos progresivamente un sistema de diseño muy simple que contiene un solo botón, pero mostraré varias de las funciones que Storybook puede ofrecer para mejorar nuestra experiencia de desarrollado y la velocidad del proyecto.Aprendermos a configurar los StoryBook utilizados en la producción por todos, desde Lonely Planet hasta Uber, pero al mismo tiempo, lo mantendremos lo más simple posible, para que podamos reutilizar estas API para nuestras necesidades futuras.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

¿Qué es un “side effect”?

2020-02-20
javascriptreactredux

En el anterior post, conocimos un poco sobre la inmutabilidad y la razon de porque deberia importarnos a la hora de escribir nuestro codigo en especial nuestros reducers.En esta ocasion, quiero abordar un poco sobre los *side effect *y como el trabajar con funciones puras nos puede servir, sin embargo, primero veamos qué hace que una función sea pura y porque está muy relacionada con la inmutabilidad.Reglas de inmutabilidadPara ser pura, una función debe seguir estas reglas:Una función pura siempre debe devolver el mismo valor cuando se le dan las mismas entradas.Una función pura no debe tener ningún efecto secundario (side effect).Los “side effects” son un término amplio, pero básicamente significa modificar cosas fuera del alcance de esa función inmediata. Algunos ejemplos de efectos secundarios …Mutar/modificar parámetros de entrada, como giveAwesomePowers (funcion del post anterior)Modificación de cualquier otro estado fuera de la función, como variables globales, o document.(anything) o window.(anything)Hacer llamadas a la APIconsole.log()Math.random()Las llamadas a la API pueden sorprenderte. Después de todo, hacer una llamada a algo comofetch('/users')podría no cambiar nada en su UI.Pero pregúntate esto: si llamó fetch('/users'), ¿podría cambiar algo en cualquier lugar? ¿Incluso fuera de tu UI?Sí. Creará una entrada en el registro de red del navegador. Creará (y quizás luego cerrará) una conexión de red al servidor. Y una vez que esa llamada llega al servidor, todas las apuestas están desactivadas. El servidor podría hacer lo que quiera, incluyendo llamar a otros servicios y hacer más mutaciones. Por lo menos, probablemente colocará una entrada en un archivo de registro en algún lugar (que es una mutación).Entonces, como dije: “side effect” es un término bastante amplio. Aquí hay una función que no tiene side effects:Puedes llamar esta función una vez, puedes llamarla un millón de veces y nada cambiará. Quiero decir, técnicamente, esto satisface la Regla 2. Llamar a esta función no causará directamente ningun efecto secundario.Además, cada vez que llame a esta función como add(1, 2) obtendrá la misma respuesta. No importa cuántas veces llame a add(1, 2) obtendrá la misma respuesta. Eso satisface la Regla 1: las mismas entradas == mismas respuestas.JS Array métodos que mutanCiertos métodos de vector mutarán el vector en el que se utiliza:push (agregar un item hasta el final)pop (eliminar un item del final)shift (eliminar un item desde el principio)unshift (agregar un item desde el principio)sortreversespliceLas funciones puras solo pueden llamar a otras funciones purasUna posible fuente de problemas es llamar a una función no pura desde una pura.La pureza es transititiva y es todo o nada. Puede escribir una función pura perfecta, pero si la finaliza con una llamada a alguna otra función que eventualmente llame a setStateo dispatch o cause algún otro tipo de efecto secundario … entonces todas las apuestas estarán desactivadas.Ahora, hay algunos tipos de efectos secundarios que son “aceptables”. Registrar mensajes con console.log está bien. Sí, técnicamente es un efecto secundario, pero no va a afectar nada.A Pure Version of giveAwesomePowersAhora podemos reescribir nuestra función teniendo en cuenta las Reglas.giveAwesomePowers — Pure functiongiveAwesomePowers — Pure functionEsto es un poco diferente ahora. En lugar de modificar a la persona, estamos creando una persona completamente nueva.Si no ha visto Object.assign, lo que hace es asignar propiedades de un objeto a otro. Puede pasarle una serie de objetos, y los combinará, de izquierda a derecha, mientras sobrescribe cualquier propiedad duplicada.(Y por “de izquierda a derecha”, quiero decir que la ejecución de Object.assign(result, a, b, c) copiará a en result, luego b, luego c).Sin embargo, no hace una fusión profunda(deep merge): solo se moverán las propiedades secundarias inmediatas de cada argumento. También, lo más importante, no crea copias o clones de las propiedades. Los asigna tal como están, manteniendo las referencias intactas.Entonces el código anterior crea un objeto vacío, luego asigna todas las propiedades de person, a ese objeto vacío y luego asigna la propiedad specialPower a ese objeto también. Otra forma de escribir esto es con el operador de propagación de objetos (spread):giveAwesomePowers — ES6 || spreadgiveAwesomePowers — ES6 || spreadPuedes leer esto como: “Cree un nuevo objeto, luego inserte las propiedades de person, luego agregue otra propiedad llamada specialPower”. Al escribir estas líneas, esta sintaxis spread es oficialmente parte de la especificación de JavaScript en ES2018.Funciones puras devuelven nuevos objetos a estrenarAhora podemos volver a ejecutar nuestro experimento desde antes, utilizando nuestra nueva versión pura degiveAwesomePowers.La gran diferencia es que esa person no fue modificada. Mafe no ha cambiado. La función creó un clon de Mafe, con todas las mismas propiedades, además de la capacidad de hacerse invisible.Esto es una especie de cosa extraña acerca de la programación funcional. Los objetos se crean y destruyen constantemente. No cambiamos a Mafe; creamos un clon, modificamos su clon y luego reemplazamos a Mafe con su clon.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

¿Qué es la inmutabilidad?

2020-02-10
javascriptreduxreact

Inmutabilidad en React y ReduxLa inmutabilidad puede ser un tema confuso, y aparece en todas partes en React, Redux y JavaScript en general.Es posible que hayas encontrado errores en los que tus componentes de React no se vuelven a renderizar, a pesar de que sabes que has cambiado las props, y alguien dice, “Deberías estar haciendo actualizaciones de estado inmutables.” Tal vez tú o uno de tus compañeros de equipo escribe regularmente reducers en Redux que mutan el estado, y nos toca corregirlos constantemente (los reducers, o a nuestros compañeros de trabajo 😄).Es complicado. Puede ser muy sutil, especialmente si no estás seguro de qué buscar. Y sinceramente, si no estás seguro de por qué es importante, es difícil preocuparse.

Introducción a Apollo Client con React para GraphQL

2020-01-30
javascriptreactgraphqltutorial

GraphQL se ha vuelto popular recientemente y es probable que reemplace la API Rest. En este tutorial, utilizaremos el Cliente Apollo para comunicarnos con la API GraphQL de GitHub. Integraremos Apollo Client con ReactJS, pero también puede usarlo con otras plataformas (VueJS, Angular, etc).

Flux Standard Action (FSA)

2020-01-20
reactjavascriptreduxtutorial

Es una especificación ligera que define la estructura de una acción, para ser implementada en librerías que usan el patrón o arquitectura Flux.El cumplimiento de FSA ayuda a los desarrolladores a crear abstracciones que pueden funcionar con diferentes implementaciones de Flux.Flux Standard Action — ExampleFlux Standard Action — ExampleTodo inicia después de que Facebook publicó su arquitectura/patrón Flux, muchas librerías implementaron la filosofía Flux, Redux fue una de ellas.Flux se puede dividir en varios conceptos Dispatcher, Store, Action y View. Pero en este post vamos a conocer la parte de Action y como trabajar con estas de una forma mas estandarizada, para mas adelante poder hacer uso de otras librerías que implementan la filosofía FSA.Antes de adentrarnos mas en el tema principal de hoy, conozcamos el concepto de Action y como es definido por flux:Actions define the internal API of your application. They capture the ways to interact with your application. They are simple objects that consist of a “type” field and data.La especificación conduciría al siguiente objeto:{ type: 'ADD_TODO', text: 'TODO content' }El único problema con este ejemplo simple es que el desarrollador puede elegir cualquier nombre de propiedad para los valores. Todos los siguientes nombres son válidos: título, nombre, texto, todoNombre, etc. Es imposible saber qué propiedades esperar del ADD_TODO en el reductor de Redux.Sería mucho más fácil trabajar con acciones de Flux, si pudiéramos hacer ciertas suposiciones sobre su forma. Tal vez la definición de un estándar común mínimo para estos patrones permitiría tener la abstracción necesaria para comunicar nuestras acciones con el reducer. Esto es algo que Flux Standard Action (FSA) viene a resolver.Para entrar un poco en detalle sobre FSA, en necesario partir de la siguiente premisa que Flux Standard Action nos proporciona sobre las acciones:Una acción DEBE:ser un objeto JavaScript simple.tener una propiedad type.Una acción PUEDEtener una propiedad error.tener una propiedad payload.tener una propiedad meta.Una acción NO DEBE incluir propiedades que no sean type, payload, error, y meta.¿pero entonces que significa cada una de estas propiedades que nuestro objeto javascript puede llegar a contener?Veamos entonces cada uno de estostypeLa propiedad requerida type identifica la naturaleza de la acción que ha ocurrido al consumidor, type es una constante de tipo StringpayloadLa propiedad opcional payload PUEDE ser cualquier tipo de valor. Representa la carga de la acción. Cualquier información sobre la acción que no sea el type o el estado de la acción debe ser parte del campo payload.Por convención, el payload DEBERÍA ser un objeto.errorLa propiedad opcional error PUEDE establecerse en verdadero si la acción representa un error.An action whose error is true is analogous to a rejected Promise. By convention, the payload SHOULD be an error object.Si el error tiene cualquier otro valor además de true, incluyendo undefined y null, la acción NO DEBE ser interpretada como un error.metaLa propiedad opcional meta PUEDE ser cualquier tipo de valor. Está destinado a cualquier información adicional que no forme parte de payload .El concepto Flux Standard Action (FSA) es usado por algunas librerías que nos puede ayudar a reducir el texto repetitivo que debemos crear para nuestras accionesLibreríasredux-actions — un conjunto de helpers para crear y manejar acciones de FSA en Redux..redux-promise — Es un middleware que admite acciones de FSA.redux-rx — Utilidades RxJS para Redux, incluido un middleware que admite acciones de FSA.Espero en una próxima ocasión tener la posibilidad de dar una introducción de como reducir el Boilerplate de Redux con Redux-Actions.¡Espero que esto haya sido útil y/o te haya hecho aprender algo nuevo!Profile@khriztianmoreno �

Estructurando la base de nuestro proyecto NodeJS

2020-01-10
nodejsexpressjsscaffoldingapijavascript

La idea de escribir este articulo nace de una necesidad que se manifesto en un meetup de la ciudad en cual asistí. Muchas de las personas que estuvieron allí, preguntaban que como sabrían donde debería estar los archivos que componen su proyecto como lo son: modelos, eventos, controllers, vistas, etc etc. Ya que en Node.JS no existía como una forma base para hacerlo y que muchos de los ejemplos visibles, nunca sustentaban la razón por la cual se construía de esa manera.

NodeSchool: Aprende por tu cuenta

2020-01-02
javascriptnodejstutorial

A la hora de querer aprender una nueva tecnología o conocer las características de algún lenguaje siempre buscamos en internet algún tutorial que nos enseñe sus conceptos, es por eso que hoy les quiero hablar sobre NodeSchool.io una iniciativa que busca enseñar por medio de talleres autoguiados el aprendizaje de estos temas.