Héctor BlisS
@blissitohace 3 años
Remix es el nuevo framework que está que arde en twitter y en la comunidad global de developers JavaScript y a pesar de que no ha explotado como otros frameworks principalmente porque esta un poco eclipsado por el auge que tienen ahora mismo NextJS y Gatsby y NuxtJS es un framework para "server side rendring" que vale mucho la pena, pues sus creadores (Ryan Florence y Michael Jackson) son miembros de la comunidad web desde siempre (since forever) además de ser los responsables de haber creado React-router también.
Remix retoma muchos principios de la web que siempre han estado presentes cuando creamos paginas web que dependen de un servidor (e.i. request-response) y que últimamente se han puesto de moda principalmente por cuestiones de SEO y accesibilidad y que estaban en desuso por que todos estábamos montados en las SPA (single page applications) aplicaciones que funcionan 100% en el cliente (navegador) y que evitan el ruteo hacia el servidor, pero que a su vez introducen mucha complejidad a la hora de escribir los sitios web, así como la capa extra que agregan para lograr trabajar con los datos que si vienen desde un servidor, cuidando la seguridad y creando tiempos de espera a veces obscenos. Curiosamente muchos nuevos developers que incluso ya se desempeñan como profesionales del "front-end" sólo conocen las SPA y no han tenido la oportunidad de trabajar con aplicaciones renderisadas por el servidor haciendo uso del poderoso protocolo HTTP. Afortunadamente ¡REMIX está aquí para retomar un millar de buenas prácticas web!
Vamos a iniciar un proyecto nuevo con Remix que nos permita crear un par de rutas y navegar entre ellas, y más adelante (en otras entradas del blog) trabajaremos con opciones más interesantes cómo el manejo de formularios vía http que trae de vuelta la comodidad de que el navegador serialice el <form>
por nosotros, incluso está en mis planes conectar algunas bases de datos que utilizo frecuentemente en mis proyectos como MongoDB y Firebase así como tratar el tema del manejo de sesiones
con las herramientas de cookies que Remix ya incluye, pero ¡hey, no corramos! tenemos que empezar por algún lado así que vamos a crear nuestro proyecto nuevo con npx: (por su puesto que necesitas tener instalado, nodejs + npm de preferencia con una versión mayor a 14)
npx create-remix@latest mi-remix-app
Eso nos va a preguntar un par de cosas sobre nuestro proyecto comenzando con decirle que si a proceder. (y)
En esta ocasión escogeremos Netlify
ya que Remix nos provee con un proyecto listo para producción y lo vamos a publicar fácilmente con Netlify y necesitamos que Remix nos incluya los archivos de configuración necesarios para hacer deploy
en un par de pasos simples.
En un futuro próximo trabajaremos más con Typescript (por obvias razones) pero por ahora para mantener este proyecto simple seleccionaremos JavaScript.
Diremos que si a instalar todo con npm y después de que haga la instalación de las bibliotecas estaremos listos para probar nuestro servidor por primera vez con:
1cd mi-remix-app 2npm run dev 3
Si todo salió bien, tendremos nuestro servidor corriendo en el puerto :3000 y podremos visitarlo en nuestro navegador, claro no es el home page más "fancy" que has visto pero hey Remix se trata de simplicidad ;)
Como podrás darte cuenta al abrir nuestro proyecto code .
(si usas vsCode) o en tu editor de código favorito, encontramos un grupo de carpetas dentro de las que destaca app
en esta carpeta se encuentra los archivos más importantes de nuestra aplicación como son root.jsx
que es el equivalente a index.js
cuando trabajábamos con create-react-app
y la carpeta routes
donde colocaremos todas las rutas de nuestro sitio web, así es Remix maneja el ruteo por nosotros simplemente creando losa archivos correspondientes dentro de esta carpeta, si abrimos esta carpeta routes
vamos a encontrar un archivo index.jsx
que representa nuestra ruta por default o home ('/'
) vamos a modificar este archivo un poco.
1export default function Index() { 2return ( 3 <div> 4 <h2>Bienvenido al inicio de mi sitio web</h2> 5 </div> 6); 7} 8 9
Remix utiliza la exportación por default para determinar cuál es el componente que se usará para rende rizar la página en esta ruta ('/'
) lo mágico de esto es que esta página fue renderizada por el servidor a pesar de que está escrita con React, y al navegador sólo se le entregó un archivo HTML reprocesado, facilitando con esto por default el control de cualquier meta tag que necesitemos aquí y haciendo más fácil la configuración SEO de nuestras rutas, es más si observas el archivo root.jsx
podrás encontrar que Remix ya incluye herramientas especificas para controlar las meta
tags e incluso las script
tags en caso de necesitar herramientas de analítica etc. Esto es algo que no controlamos dentro de las rutas con create-react-app
+ react-router-dom
siendo el principal motivo para buscar el renderizado vía servidor.
Vamos a crear un par de rutas nuevas, y esto lo hacemos simplemente creando un archivo más dentro de la carpeta routes
vamos a crear la ruta contacto.jsx
y agregaremos un componente nuevo dentro del archivo.
1export default function Contacto() { 2 3return ( 4 <div> 5 <h2>¿Necesitas training para tu equipo?</h2> 6 <p> 7 ¡hablemos! 8 </p> 9 <input type="text" placeholder="escribe tu nombre" /> 10 </div> 11); 12} 13 14
Guardamos el archivo y vamos al navegador a la ruta http://localhost:3000/contacto
boom! increíblemente simple ¿no? yo quería que la ruta se llamara 'contacto' y es por ello que nombre el archivo de esa forma, por su puesto que existen mejores estrategias para la internacionalización de las rutas, pero por ahora así está bien.
Ahora vamos a navegar entre nuestra homepage
y contacto
, vamos a usar una herramienta que Remix nos incluye Link
, no olvidemos que Remix fue creado por las mismas personas que inventaron la herramienta de ruteo más usada en React así que sí, este componente Link
resulta muy familiar. Nuestros componentes quedan así cada uno en su respectivo archivo (contacto.jsx
, index.jsx
)
1import { Link } from "remix"; 2export default function Contacto() { 3 4return ( 5 <div> 6 <h2>¿Necesitas training para tu equipo?</h2> 7 <Link to="/"> 8 Volver 9 </Link> 10 <p> 11 ¡hablemos! 12 </p> 13 <input type="text" placeholder="escribe tu nombre" /> 14 </div> 15); 16} 17////////////////////////////////////////////////////////////////// 18import { Link } from "remix"; 19export default function Index() { 20 21return ( 22 <div> 23 <h2>Bienvenido al inicio de mi sitio web</h2> 24 <Link to="/contacto"> 25 contáctanos 26 </Link> 27 </div> 28); 29} 30 31
Ya sé no tenemos estilos ni nada por ahora y se ve horrible, pero hey concentrémonos en lo rápido que estamos creando una navegación fluida que además si observas bien, el navegador no se refresca a pesar de que está sucediendo vía server side rendering
tenemos las cualidades de un SPA ¡gratis! ¿cool ha?
En remix también podemos crear rutas dinámicas que nos permitan capturar parámetros en la url, esto es muy útil cuando esperamos que el parámetro represente algún id
o slug
que nos permita identificar un objeto especifico y poder buscarlo en nuestra base de datos o incluso en el servicio de un tercero, pero para nuestro demo vamos a crear algo muy simple. Creamos el archivo success-$name.jsx
dentro de nuestra carpeta routes
y colocamos este componente dentro.
1export default function Success() { 2return ( 3 <div> 4 <h2>{name} Hemos recibido tu correo</h2> 5 <p>pronto nos pondremos en contacto contigo</p> 6 </div> 7); 8} 9 10
ya puedes imaginar qué es lo que queremos hacer aquí, esa variable name
la vamos a conseguir de los params de la ruta, pero aún no hemos terminado, es hora de usar una de las herramientas más interesantes de Remix para conseguir data desde el servidor sin molestarnos en escribir ninguna petición asíncrona y sin usar fetch
, Ajax
o bibliotecas más modernas cómo useQuery
. Nuestro componente contacto.jsx
queda así:
1import { useState } from "react"; 2import { Link } from "remix"; 3 4export default function Contacto() { 5const [name, setName] = useState('') 6const handleChange = ({target:{value}}) => setName(value) 7 8return ( 9 <div> 10 <h2>¿Necesitas training para tu equipo?</h2> 11 <Link to="/"> 12 Volver 13 </Link> 14 <p> 15 ¡hablemos! 16 </p> 17 <input onChange={handleChange} type="text" placeholder="nombre" /> 18 <Link to={`/success-${name}`}> 19 <button disabled={name===''} > 20 Enviar 21 </button> 22 </Link> 23 </div> 24); 25} 26 27
Si observas la modificación, podemos usar nuestros respectivos y amados useState
y cualquier otro hook a los que ya estamos acostumbrados en React, sin limitaciones pudiendo explotar todas las habilidades que nos brinda React para enriquecer la experiencia de nuestro usuario con todo el poder de JavaScript en el servidor. Significa que podemos mezclar las potencias tanto del SSR y ruteo del backend más el dinamismo y flexibilidad de JS en el cliente, he aquí la razón del nombre: REMIX.
Si escribimos nuestro nombre y presionamos enviar, Remix nos direccionará a nuestra ruta success-$name.jsx
y observaremos que $name
se sustituye con el nombre que nosotros ingresamos, ¡perfecto! es hora de usar ese dato (variable o param) que nos hemos proporcionado por la url.
Vamos a usar la variable $name
que hemos colocado intencionalmente en el nombre de nuestra ruta, que también es el nombre de nuestro archivo y para ello vamos a usar otra herramienta que Remix nos proporciona para poder escribir código que se ejecutara en el servidor pero que no se separa en realidad de nuestra ruta, es decir, vamos a usar una pequeña función que se ejecutará sólo en el servidor antes de que nuestra ruta se renderice en el cliente pero vamos a escribirla en el mismo archivo donde escribimos nuestro componente de React:
1import { useLoaderData } from "remix"; 2 3// loader sólo corre en el servidor 4export function loader({params}){ 5 const name = params.name 6 return name 7} 8 9// Success es un componente de react que corre en el cliente 10export default function Success() { 11const name = useLoaderData() 12return ( 13 <div> 14 <h2>Gracias {name} Hemos recibido tu correo</h2> 15 <p>pronto nos pondremos en contacto contigo</p> 16 </div> 17); 18} 19 20
¡Pum! así es como Remix nos permite trabajar con la información que viaja en la ruta, este ejemplo es en extremo simple, pero si tienes algo de experiencia con desarrollo web, aquí es donde consigues datos de otras APIs, Bases de datos etc. Remix nos permite hacer el tratamiento de los datos en el lugar correcto ( y más seguro) el servidor, mientras que con el hook useLoaderData()
podemos de manera muy simple consumir esos datos simplemente porque la función loader
nos los entrega en el return
Es muy importante no olvidar la palabra
export
en la función loader porque es la manera en la que Remix ejecuta nuestra función correctamente en el ciclo request-response, además de nombrar la funciónloader
siempre.
¡Hey mírate! estas escribiendo código en el backend y en el frontend en cuestión de minutos con Remix, eso te convierte en full-stack developer no? ;)
Pero por el momento vamos a dejar este tutorial de este tamaño, retomaremos este proyecto para mostrar más herramientas de Remix para hacer peticiones HTTP (get, post, put, delete) y profundizar en las herramientas más avanzadas de este increíble framework que nos permite escribir aplicaciones completas (server-client) en tiempo record.
Personalmente me encantan las herramientas que me aceleran, me permiten concentrarme en lo que construyo y no en resolver problemas de configuración o que me obligan a invertir tiempo en reaprender a hacer algo que http y el navegador ya resolvían desde hace mucho tiempo, Remix me recuerda los bellos días cuando aprendía a usar php o Django y la seguridad estaba implícita en el código que podía escribir en el servidor y nunca llegaba al cliente (nunca público) y bueno, hasta ahora estoy disfrutando cada intento de sustituir mis herramientas regulares (expressJS) con Remix porque hasta ahora he podido hacerlo todo y ¡mucho más rápido! así que ten por seguro que seguiré compartiendo más sobre Remix.
Por ahora espero este pequeñísimo intro arroje algo de luz para que te hagas de tu propia opinión sobre Remix. Te agradezco el tiempo invertido en esta lectura y nos vemos en el siguiente para subir nuestro proyecto a Netlify fácilmente.
Happy Coding! ❤ hectorbliss