👨🏼‍💻

khriztianmoreno's Blog

Inicio Etiquetas Acerca |

Posts with tag nodejs

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 �

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

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

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 �

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.