Remixando Cómo Donamos

Rate this content
Bookmark

Una revisión de cómo estamos utilizando Remix en Daffy.org para cambiar la forma en que las personas donan a organizaciones benéficas.


Hablaremos sobre por qué decidimos usar Remix, cómo lo hemos utilizado y migrado desde nuestra aplicación frontend anterior, y algunos patrones y bibliotecas que hemos desarrollado internamente.

32 min
18 Nov, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Daphne utiliza Remix para su aplicación web, beneficiándose de su resistencia, límites de errores, límites de caché y mejora progresiva. Remix simplifica el envío de formularios, la autorización y la validación, y permite una refactorización más fácil y evitar la duplicación de código. Next y Remix se utilizan juntos, con Remix sirviendo como el backend para el frontend y manejando la agregación de datos. Remix proporciona funciones de consulta para obtener datos, mutaciones para la validación de datos de formularios y llamadas a API, y convenciones personalizadas utilizando la exportación de manejo. La migración a Remix resultó en archivos JavaScript más pequeños, una navegación más rápida y la capacidad de precargar datos y activos. El proceso de migración tomó alrededor de nueve meses e involucró la mezcla de Next.js y Remix utilizando Express. Contratar a alguien para trabajar en Remix es más fácil que contratar para otros frameworks.

Available in English

1. Introducción a Daphne y Remix

Short description:

Hola, bienvenidos a mi presentación. Soy Sergio Salambri, desarrollador web en Daphne, y voy a hablar sobre cómo usamos Daphne y Remix en Daphne. Daphne es una plataforma para ayudar a las personas a donar a las organizaciones benéficas en las que se preocupan de manera automatizada. Usamos Remix para nuestra aplicación web porque proporciona resiliencia, límites de errores, límites de caché y mejora progresiva. Con Remix, podemos capturar errores inesperados, mostrar errores conocidos y asegurarnos de que la aplicación siga siendo utilizable incluso si JavaScript no se carga. Además, elegimos RemixBoot por sus capacidades de mutación de formularios.

a hablar sobre cómo usamos Daphne, cómo usamos Remix en Daphne. Entonces, ¿qué es Daphne? Daphne es una plataforma para ayudar a las personas a donar a las organizaciones benéficas en las que se preocupan de manera automatizada. Para hacer eso, proporcionamos tanto una aplicación iOS como una aplicación web y usamos Remix para esa aplicación web. También usamos Remix para otras aplicaciones. Nos vamos a enfocar en cómo lo usamos para la aplicación web principal. Eso es lo que los usuarios utilizan. Así que primero empezamos a usar y construir el front-end. Daphne o MVP era una aplicación de enrutador que se servía desde una ruta de Rails y se compilaba con Rails webpacker. Funcionaba muy bien para las pruebas de concepto del MVP, pero luego lo cambiamos a Next.js para las páginas de aterrizaje y la web porque queríamos tener un servidor y otras características. Tuvimos algunos problemas con la configuración. Las páginas eran lentas en una conexión lenta al sitio web. Si había un error en una de nuestras llamadas a la API para obtener data para renderizar en la página, se bloquearían y mostrarían un error sospechado. Además, los forms eran demasiado complejos para validar y ejecutar errores. Teníamos duplicación innecesaria de código. También el código de fragmentación en la función get server-side props era demasiado complejo, porque necesitas obtenerlo en funciones de alto orden. Así que decidimos que necesitábamos usar algo diferente, y elegimos usar RemixBoot. Y la razón para eso es la primera, la resiliencia. La resiliencia es qué tan bien una aplicación puede seguir funcionando en caso de un error. Remix no hace que tu aplicación funcione todo el tiempo si hay un error, pero te ayuda mucho a llegar allí o cerca de allí. Con límites de errores, podemos capturar cualquier error inesperado y mostrar algo al usuario, como, oye, algo salió mal. Vamos a – ahora sabemos de esto, pero puedes contactar soporte si necesitas más ayuda. Con límites de caché, podemos mostrar cualquier error conocido. Si el usuario va a una organización benéfica y esa organización no existe, no es divertido. O si un proveedor de usuario no existe, no es divertido. Si quieren hacer algo que requiere más dinero en su cuenta, podemos mostrar un mensaje de pago faltante o una interfaz de usuario con límites de caché. También podemos usar Mejora Progresiva. Si JavaScript no se carga por alguna razón, la aplicación sigue siendo en su mayoría utilizable. Al menos pueden acceder al contenido.

2. Simplificando el Envío de Formularios y la Migración a Remix

Short description:

Con Remix, el proceso de envío de formularios, autorización y validación se vuelve mucho más sencillo. La llamada a la acción está en el mismo archivo que el formulario, lo que facilita entender el flujo de la aplicación. Remix también ofrece convenciones y separación de responsabilidades, lo que permite una refactorización más fácil y evitar la duplicación de código. Además, la migración a Remix se realizó ejecutando Remix y Next juntos, utilizando el servidor Express para ejecutar ambas aplicaciones en un solo proceso.

Otra razón fue la mutación de formularios. Con la pila anterior, teníamos que hacer muchas cosas para realizar una mutación, como crear un formulario, un estado para la entrada, serializarlo, enviarlo en un fetch a una API, crear la API en otro archivo, enviar autorización, validar los datos y enviarlos a nuestra API de Rails. Con Remix, esto se vuelve mucho más sencillo. Simplemente renderizamos el formulario, exportamos la acción en el mismo archivo donde vive el formulario. Podemos realizar el servicio y lanzar la autorización y validación de los datos antes de enviarlos a Rails y funciona. Es mucho más sencillo.

La llamada a la acción también está en el mismo archivo del formulario. Eso es un gran beneficio para poder saber qué está sucediendo en una ruta. Vamos a una ruta, entonces hay un formulario. Vamos a la acción. Sabemos qué está haciendo ese formulario. También podemos agregar validación con Solve. Los formularios de múltiples pasos pueden funcionar de manera mucho más sencilla con JavaScript y con el botón de retroceso, algo que no teníamos antes. Y podemos utilizar la transición del usuario para mejorar la experiencia de los usuarios. Y así, desde estados de carga hasta interfaces de usuario optimistas. Las convenciones y la separación de responsabilidades también es otra razón por la que elegimos Remix. Los archivos de rutas ayudan mucho con la refactorización. Podemos simplemente eliminar un archivo de ruta y con eso eliminar la acción, el cargador, el componente, los enlaces, todo. También las rutas anidadas ayudan a evitar la duplicación. No necesitamos mover código a otro archivo e importarlo en muchos archivos como encabezados, a través de las rutas. Simplemente creamos un patrón, una ruta de diseño, y colocamos dentro todo lo que necesita ese encabezado y listo. Y el componente luego vive en la ruta. Los cargadores y las acciones también utilizan estándares. Y pasamos menos tiempo en la documentación de Remix y más tiempo en la documentación de Mozilla Developer Network. También significa que contratar y enseñar la pila es más sencillo. Contratamos a alguien que no conocía Remix y ella aprendió Remix para la entrevista y pasó la entrevista y otros desarrolladores enfocados en el backend pudieron aprender Remix súper rápido, en un día o menos de un día, y comenzaron a usarlo. Ahora, cómo nos migramos a Remix. Sabíamos que queríamos usar Remix, pero aún teníamos esta gran aplicación de Next. Lo que hicimos, lo primero fue que no podíamos migrar todo de una vez, así que decidimos ejecutar Remix y Next juntos. Para hacer esto, aprovechamos que Remix se puede conectar a un servidor Express y Next también se puede conectar a un servidor Express.

3. Usando Next y Remix Juntos

Short description:

Enviamos solicitudes a Next para APIs y activos, pero todo lo demás va a Remix. Manejamos los errores de Next inicialmente, pero eventualmente cambiamos a enviar todas las solicitudes a Remix. Compartimos el estado de autenticación entre aplicaciones usando un sessionStore compartido. Durante la migración, utilizamos navegación de página completa para enlaces y formularios. Ahora, Remix sirve como el backend para nuestro frontend, agregando datos de múltiples puntos finales de API. Los cargadores manejan la obtención, filtrado y transformación de datos, simplificando nuestros componentes de React.

Usamos express para ejecutar ambos procesos, ambas aplicaciones en un solo proceso. Enviamos todo desde /_next/whatever a Next, para que pueda manejar APIs y enviar activos. Usamos express static para la compilación pública, la carpeta pública y la compilación pública de Remix. Enviamos una solicitud específica a Remix y el resto de las solicitudes a Next inicialmente. Esto significa que al principio tuvimos que manejar los errores de Next, pero eventualmente cambiamos y comenzamos a enviar todas las solicitudes a Remix de forma predeterminada y solo las solicitudes específicas a NextJS. Hicimos esto cuando movimos toda nuestra caché, todas las rutas, como el perfil de usuario, a Remix, y eso nos permitió hacer el cambio y decir, ok, a partir de ahora todo va a Remix excepto esta ruta, como la ruta de API de Next o algunas rutas que aún estábamos sirviendo con HTML para Next. También tuvimos que compartir el estado de autenticación porque el cambio de una aplicación a otra para el usuario debería haber sido el mismo. El usuario no sabía si la ruta estaba usando Remix o Next, excepto probablemente porque era más rápido. Así que creamos un mixout. Cambiamos el SDK de Next.js a RemixOut con la estrategia Out0 y luego nos dimos cuenta de que el objeto de almacenamiento de sesión de Remix en realidad no está vinculado de ninguna manera a Remix. Podemos usarlo en Next. Puedes instalar esa parte en la aplicación de Next y hacer que funcione. Así puedes ver cómo puedes pasar el valor de res.headers.cookie a sessionStore.getSession y obtener la sesión, y luego confirmar la sesión y obtener la cadena para enviar a res.setHeader. Y de la misma manera podemos hacerlo con Remix. Así que compartimos este sessionStore para poder compartir el estado de autenticación entre aplicaciones. Finalmente, otro problema que tuvimos fue que los enlaces de Remix apuntaban a aplicaciones de Next mientras intentábamos hacer una navegación del lado del cliente, y eso fallaba porque la ruta aún no existía en Remix. Y lo mismo sucedía en sentido contrario. Los enlaces de Next que apuntaban a Remix intentaban hacer lo mismo, intentando cargar la siguiente ruta a la que el usuario estaba navegando usando Next, pero eso ya no existía. La solución fue, mientras la migración aún estaba en curso, agregamos reload document en los componentes de Remix y evitamos usar el componente de enlace de Next. Así que cada enlace era una navegación de página completa. Lo mismo con los formularios. Cada formulario causaba una navegación de página completa incluso si el enlace o el formulario apuntaban a una ruta que ya sabíamos que estaba usando Remix. Así que establecimos la línea de base, básicamente todo usaba navegación de página completa, y una vez que la migración estuvo lista y sabíamos que no había más código de Next.js en ejecución en producción, eliminamos todos los documentos de recarga y todos se convirtieron en una aplicación de una sola página. Ahora cómo usamos Remix en Daffin. Primero, Remix es un backend para frontend para nosotros. El usuario interactúa solo con Remix, no hay forma de que el usuario vea una solicitud a la API de Rails, simplemente la envía a Remix y desde allí a Rails, y usamos esto para agregar datos de múltiples puntos finales de nuestra API. En el lado del servidor, en los cargadores, simplemente podemos obtener múltiples puntos finales. Obtenemos los datos y también los filtramos en el lado del servidor, y podemos transformar los datos. Por ejemplo, convertimos objetos de fecha en mensajes localizados o números en la cantidad de cadena localizada. Y debido a esto, porque la mayoría de estas cosas que solíamos hacer en la interfaz de usuario ahora están en los cargadores, nuestros componentes de React son más simples porque se centran solo en la interfaz de usuario, se centran en obtener los datos de useLoaderData y mostrarlos al usuario, y algunos estados o esfuerzos específicos para la integración principalmente con servicios de terceros.

4. Estructura de archivos raíz y acoplamiento de componentes

Short description:

Tenemos la idea de que un archivo raíz contiene todo lo necesario, evitando el acoplamiento de componentes con datos. Los componentes compartidos reciben datos de las props y encuentran exactamente lo que necesitan. Los componentes complejos están vinculados a la raíz y residen en la propia raíz.

Además, tenemos la idea de que un archivo raíz debe contener todo lo que necesitan, al menos tanto como sea posible. Solo movemos los componentes a la carpeta 'components' de las aplicaciones si son realmente compartidos, es decir, si los usamos en casi todas las raíces o al menos en más de tres. Por lo tanto, sabemos antes de mover un componente a esta carpeta que realmente se va a utilizar en muchas partes y no está vinculado a los datos. Esto permite una refactorización sencilla de las raíces porque si todo está en la raíz, simplemente podemos eliminar la raíz y eliminar todo el código relacionado. No hay forma de que eliminemos una raíz y dejemos el componente en la carpeta 'components' porque no estamos seguros si algo más lo está utilizando. También evitamos el acoplamiento de componentes con los datos. Debido a que todos nuestros componentes compartidos solo reciben datos de las props y no de los datos. Y encontrarán exactamente lo que necesitan. Y muchos componentes simples porque si son componentes complejos, generalmente están vinculados a lo que

5. Funciones de consulta, Mutaciones y Manejo de Errores

Short description:

Tenemos el concepto de funciones de consulta en Remix, que son funciones asíncronas que obtienen datos de la API y manejan el filtrado, análisis y transformación. Estas funciones se colocan al final del código del cargador. Los errores en consultas importantes hacen que la captura principal falle dentro del cargador, mientras que otros fallan silenciosamente. Manejamos las mutaciones de manera similar, validando los datos del formulario con un esquema SOD y enviándolos a la API. Devolvemos respuestas JSON con estados de éxito o error según corresponda. También manejamos errores de interfaz de usuario moviendo partes de la interfaz de usuario a componentes separados y renderizándolos en función de la disponibilidad de datos. Además, definimos convenciones personalizadas utilizando la exportación de manejo y tenemos un cliente de API seguro en cuanto a tipos para garantizar la seguridad de tipos al obtener datos de nuestra propia API.

el root está haciendo específicamente y duerme en el propio root. También tenemos esta idea de una función de consulta. Así es como se ve un cargador en Remix, el código inicial donde autenticamos al usuario, creamos clientes de API, instancias y cosas así se espera que no fallen. Entonces si fallan, queremos que el límite de error se renderice. Luego intentamos capturar todo lo que se espera que pueda fallar. Si hay un error, capturamos la excepción y la enviamos a Sentry. Y también devolvemos o verdadero una respuesta para informar al usuario que algo salió mal. Devolvemos verdadero cuando la palabra root es mala, y devolvemos cuando aún podemos renderizar parte de ella. Y las funciones de consulta son estas funciones para obtener algo, funciones asíncronas que tenemos dentro del cargador al final del código del cargador donde obtenemos data de la API. También lo filtramos o analizamos o transformamos allí para que el código esté en una sola función. Y dentro de esta función, podemos intentar capturar la solicitud. Esto significa que si la obtención de donaciones falla, en este caso, queremos que el root falle porque si estás viendo una donación específica, nada tiene sentido sin esos data. Pero si la obtención de organizaciones benéficas falla, podemos devolver nulo y capturar la excepción para enviarla a Sentry. Entonces sabemos que algo falló, pero para el usuario lo que va a suceder es que la lista de organizaciones benéficas desaparece de la interfaz de usuario. Por lo tanto, las consultas importantes hacen que la captura principal falle dentro del cargador pero las demás fallan silenciosamente. Hacemos algo similar con las mutaciones. Entonces la mutación es nuevamente una función que colocamos en la parte inferior de la acción donde creamos el esquema SOD, validamos los datos del formulario con el esquema SOD y los enviamos a la API. Y si es un éxito, podemos devolver JSON con el estado de éxito o un error rojo o lo que sea necesario. Y si hay un error aleatorio, verificamos si es un error SOD, lo devolvemos en JSON con un estado de error y la lista de mensajes de error. Si no es un error SOD, significa que algo más falló, recibimos su recepción y mostramos un mensaje que generalmente le indica al usuario que se comunique con el soporte técnico que ya conocemos el error. También manejamos errores en la interfaz de usuario de esta manera, por lo que tenemos el límite de caché que en caso de que el cargador falle, el root falla. Pero movemos una parte de la interfaz de usuario de la raíz a diferentes componentes, y dentro de esos componentes que viven en el mismo archivo que la raíz, llamamos a user.data, obtenemos los data que necesitamos y lo renderizamos, y si el data es nulo, simplemente devolvemos nulo para ocultar esa parte de la interfaz. También definimos convenciones personalizadas utilizando la exportación de manejo. La mayoría de estas convenciones personalizadas no forman parte de Remick Utils, cosas como scripts de hidratación y enlaces dinámicos y datos estructurados son parte de Remick Utils, y tenemos este tipo global, Daffy.handle, al que podemos adjuntar nuestra exportación de manejo y definir lo que el root puede establecer allí. Entonces nuestros roots definen si necesitan o no javascript, si necesitan scripts externos, pueden cargarlo de esa manera. También extendemos esta convención para diferentes diseños, por lo que el handle de embarque tiene convenciones diferentes adjuntas a las globales. Lo mismo ocurre con el diseño en el handle de la aplicación y puedes ver, por ejemplo, en el handle de la aplicación tenemos este componente aside que recibe las props del cargador data y esto permite que el diseño de la aplicación renderice la barra lateral con un aside, pero lo renderice en un diseño más grande con las rutas secundarias específicas de la raíz dentro de otro lugar. Por lo tanto, podemos usar esto como una forma de definir espacios o luego venderlo de alguna manera para diferentes partes del diseño. También tenemos un cliente de API seguro en cuanto a tipos para no usar algo como Prisma porque obtenemos una API. Entonces, para tener seguridad de tipos cuando obtenemos datos de nuestra propia API, definimos un esquema con sort, exportamos, inferimos el tipo a partir de ahí y cuando obtenemos la API, simplemente analizamos los datos tal como vienen de sort con sort y dejamos que falle si hay un error. Entonces, si hay un error allí, sabemos que algo cambió en la API que no se esperaba que cambiara y podemos revisar revisamos el error y ver qué sucedió y si no y si algo funcionó correctamente el valor de retorno del método de la API va a tener el tipo correcto con el tipo de donación del esquema.

6. Rutas de Recursos y Bibliotecas de Remix

Short description:

Utilizamos rutas de recursos para generar PDF y imágenes de Open Graph. La biblioteca React PDF se utiliza para renderizar PDF con soporte de localización de Y18-next. Para las imágenes de Open Graph, renderizamos SVG y las transformamos según sea necesario. RemixAdafi ha contribuido a la comunidad de Remix, lo que ha llevado a la creación de RemixUtils, RemixOut y RemixY18next. Estas bibliotecas proporcionan varias características e integraciones. ¡Gracias por acompañarme!

También utilizamos muchas rutas de recursos para diferentes cosas. Por ejemplo, generamos PDF porque tenemos que proporcionar a los usuarios un informe sobre la donación con fines fiscales. Por lo tanto, utilizamos una biblioteca de PDF de React para renderizar un React dentro de una ruta de recurso y generar un PDF. Localizamos el PDF utilizando la biblioteca Y18-next y luego, después de renderizar el PDF, enviamos una respuesta utilizando el ayudante de PDF de RemixUtils y de esta manera podemos generar un PDF dinámico con React. También utilizamos rutas de recursos para imágenes de Open Graph. De la misma manera que obtenemos parámetros de los parámetros de búsqueda de la URL, utilizamos React para renderizar un SVG como una cadena. Si el usuario espera una respuesta SVG, simplemente la devolvemos. Si no, podemos transformar el SVG a otro formato como PNG, JPG, WebP, etc., y guardar el archivo con una cabecera de tipo de contenido. De esta manera, podemos optimizar las imágenes para OpenGraph según sea necesario. RemixAdafi ha contribuido a la comunidad de Remix porque se extrajeron muchas cosas de allí. RemixUtils existe. Gracias a RemixAdafi, utilizamos useHydrated solo en el cliente, useGlobalPendingState y más cosas provienen de funciones y componentes internos. Lo utilizamos en Adafi y luego lo extraemos a RemixUtils. RemixOut nació debido a la necesidad de implementar la autenticación de Auth0. En Dafi, publiqué el primer borrador con mi intención inicial y luego, a partir de la prueba de concepto que tenemos de Remix, creamos la versión 1 de RemixOut con la estrategia de Auth0 que luego se extrajo a otro paquete y la biblioteca creció con la comunidad. RemixY18next también existe gracias a Dafi que utiliza Remix porque necesitamos localizar la aplicación. La aplicación en realidad solo está en inglés pero ya admitimos la localización. Elegimos Y18next traducido por ellos. Mi implementación inicial se publicó como un artículo. Luego extraímos la biblioteca con el código de salida. Lo utilizamos como Y18next a partir de la prueba de concepto de Dafi. Así se creó la biblioteca y la comunidad comenzó a contribuir. Eso es todo. Gracias por acompañarme. Sergio, ¿cómo estás hoy? Estoy bien. Oh, bien. Bueno, esa fue una charla increíble. Muchas gracias. Queremos pasar a Slido.

QnA

Migración de Proyectos Existentes a Remix

Short description:

Preguntamos a la audiencia si han migrado un proyecto existente a Remix. El 53% dijo que no, pero les gustaría hacerlo, mientras que el 38% dijo que sí. Solo el 6% no tiene planes de migrar. Es genial ver que muchas personas están planeando migrar. La característica favorita de Remix mencionada por la audiencia son las mutaciones, que se considera la parte más difícil de cualquier aplicación. El proceso de migración tomó alrededor de nueve meses, comenzando en enero y finalizando en septiembre. La migración se realizó de forma incremental, aprovechando las oportunidades de rediseño y los espacios de trabajo vacíos.

y veamos cuáles fueron los resultados de la encuesta. Permítanme mostrarles mi pantalla. Preguntamos, ¿han migrado un proyecto existente a Remix? Y el 53% de las personas dijo que no, aún no lo han migrado, pero les gustaría hacerlo. Y luego algunas personas dijeron que sí, aproximadamente el 38%. Y luego nadie, no, no tengo planes, alrededor del 6%. Así que muy poca gente no quiere migrar en absoluto. Pero es genial que muchas personas estén planeando hacerlo, ¿verdad? Sí, sí. Deberían, deberían seguir adelante con eso. Esperemos que esta charla les haya ayudado a motivarse y comenzar a migrar sus aplicaciones. Y no olviden que siempre pueden unirse a nosotros en slido.com y el código es 1-818 si quieren responder a alguna de estas encuestas que estamos haciendo. Muy bien, volvamos a las preguntas y respuestas. Tenemos una pregunta que hicimos a la audiencia al principio y ahora le preguntamos a cada orador, nos gustaría saber cuál es su característica favorita de Remix. Creo que es la misma. La mayoría son las mutaciones. Sí. Es la parte más difícil en cualquier aplicación. Es fácil leer data. Es difícil mutarlo correctamente y volver a validar. Y todas las cosas que Remix hace en torno a eso, es súper fácil con acciones y forms. Sí, creo que podríamos profundizar en eso en una pregunta más adelante. Pero esa es una respuesta muy popular a esa pregunta, las mutaciones. Escuchamos mucho sobre los cargadores y las acciones. Y creo que esa es una característica muy popular y solicitada también. Entonces, ¿cuánto tiempo te llevó realmente hacer la migración de la que hablaste? Comenzamos en enero de este año. Y si no me equivoco en mi memoria, lo completamos en septiembre. Así que fueron alrededor de nueve meses para hacer la migración mientras seguimos agregando más características. De acuerdo. ¿Cómo fue ese proceso para ti, entonces, tomando ese tiempo? ¿Pudiste cambiar e migrar tu aplicación de forma incremental? Sí. Bueno, hacemos eso. Como somos una pequeña startup, todavía estamos descubriendo muchas cosas en nuestro producto. Entonces, cuando rediseñamos cosas para mejorar cómo funcionan, aprovechamos esa oportunidad para moverlas a Remix y construir una nueva versión, el Rendering Remix. Y luego cuando teníamos algunos espacios vacíos de trabajo, no teníamos nada más que hacer durante unos días, aprovechábamos ese tiempo para migrar otras cosas que no eran tan importantes y que no tocábamos tanto, pero que teníamos en NextJS, así que las migrábamos a Remix.

Mezclando Next.js y Remix

Short description:

Para mezclar Next.js y Remix juntos, utilizamos Express para ejecutar ambas aplicaciones en el mismo servidor. Compartimos el estado de autenticación y aprovechamos los patrones de interfaz de Remix. En lugar de realizar una carga pesada de datos en el lado del cliente, utilizamos GetServerSideProps y realizamos una transición fácil al Loader de Remix. La lógica del código se mantuvo igual, con solo ajustes menores en la lectura de solicitudes y el envío de respuestas.

¿Cuáles son algunos de los procesos que utilizaste para realizar esos cambios incrementales? Porque te moviste de Next.js a Remix, que tienen dos APIs muy diferentes. ¿Cómo lograste mezclarlos? Bueno, lo que hicimos fue utilizar Express para ejecutar ambas aplicaciones en el mismo servidor utilizando un solo proceso, y luego tuvimos que compartir el estado de autenticación después de descubrir que mover las cosas básicamente revelaba todo desde cero en Remix, tal vez reutilizando parte de la interfaz de usuario. Afortunadamente para nosotros, porque realmente me gustan muchos de los patrones de Remix, no hicimos demasiadas cosas en el lado del cliente, como la obtención de datos, así que utilizamos GetServerSideProps. Mover de GetServerSideProps a Loader no es tan difícil como si hubiéramos utilizado otra biblioteca para consultar datos en el lado del cliente. De hecho, es interesante que casi podrías buscar y reemplazar tus GetServerSideProps con Loader y obtener los datos que necesitas para tu ruta. Me gusta eso. Sí, gran parte del código es el mismo. Solo necesitas cambiar cómo leer las cosas de la solicitud y cómo enviar las cosas en la respuesta. Pero el resto del código, la lógica real que utilizas allí, es la misma. Genial. Supongo que eso lo haría un poco más fácil.

Beneficios de migrar a Remix

Short description:

La migración a Remix ha resultado en archivos JavaScript más pequeños, una navegación más rápida y la capacidad de precargar datos y activos. El enrutador de Remix permite la carga incremental de componentes necesarios. El mejoramiento progresivo en Remix garantiza que la aplicación funcione sin JavaScript y la mejora para los usuarios con JavaScript. Esto es particularmente importante para nuestra aplicación financiera. Utilizamos enlaces y formularios en Remix para mantener la funcionalidad incluso sin JavaScript. Convencer a nuestro equipo de migrar a Remix fue un proceso que comenzó cuando nos dimos cuenta de la necesidad de una solución mejor que los enrutadores de React configurados por Rails.

Entonces, ¿cuáles son algunos de los beneficios que has visto al migrar de React o de Remix en tu aplicación? Tenemos archivos JavaScript mucho más pequeños en el cliente. Por lo tanto, nuestra aplicación se siente más rápida cuando navegas con esta función de precarga de enlaces. Remix puede precargar no solo el código, sino también los datos y otros activos. Entonces, si tenemos imágenes que hemos precargado, puede obtenerlas, y si tenemos un cargador en la siguiente ruta, también podemos comenzar a precargar antes de que el usuario realmente haga clic en un enlace y navegar más rápido a la otra página, incluso si estamos haciendo representación en el servidor todo el tiempo.

Sí. Entonces, tal vez tenga que ver con la forma en que el enrutador de Remix está configurado y es capaz de cargar incrementalmente algunas de esas cosas que necesitas. Sí. Sí, genial. Bien, al hacer el cambio de Next.js a Remix, mencionaste que el mejoramiento progresivo también es una de las razones. ¿Puedes explicar más sobre eso y cómo Remix maneja el mejoramiento progresivo? Sí. Para aquellos que no lo saben, el mejoramiento progresivo es esta idea de que tu aplicación funciona sin JavaScript y luego lo mejoras para que funcione mejor para las personas con JavaScript, que suele ser la mayoría de los usuarios. En nuestro caso, trabajamos con dinero y si la aplicación no funciona, es preocupante para los usuarios, ¿verdad? Tienes mi dinero ahí. Incluso si ya donaste, cuando nos das el dinero, realmente es tu dinero. Y utilizar el mejoramiento progresivo significa que si hay un error en nuestro JavaScript del lado del cliente, aún puedes verlo y usarlo. Muchas cosas, no todo, pero muchas cosas siguen funcionando con el JavaScript, como los formularios y cosas así. Por lo tanto, la mayoría de la aplicación se puede utilizar incluso sin JavaScript. Y eso es cómo el Mejoramiento Progresivo nos está ayudando. Y esto se puede hacer en Remix porque, ya sabes, Remix utiliza enlaces para navegar y el enlace es un ancla y utiliza el componente de formulario, que es una aplicación. Y todo sigue funcionando de esa manera.

En realidad, eso también tiene mucho sentido, porque estás trabajando con ese dinero. Quieres darle al usuario comentarios sobre lo que están haciendo en tu aplicación. Entonces necesitas tener ese Mejoramiento Progresivo. Es como si esto estuviera funcionando en segundo plano, pero no puedes verlo hasta que se haya terminado. Pero vamos a mostrarte progresivamente una actualización optimista con la esperanza de que esos datos regresen, ¿verdad? Sí. Genial. Ahora tenemos un par de preguntas de la audiencia. Chris dijo, ¿tuviste algún problema para convencer a tu equipo de migrar a Remix? Creo que dijiste de Next.js, y ¿cómo lo haces al principio? Comencé a pensar en convencer al equipo de usar Remix. Recién estábamos comenzando el front-end.

Migración a Remix y Estructura de Monorepo

Short description:

Inicialmente construimos una prueba de concepto con enrutadores de React, pero eventualmente decidimos migrar a Remix debido a problemas de rendimiento. El CTO estaba inicialmente indeciso de usar Remix porque era un framework de pago y podría dificultar la contratación. Sin embargo, después de probar Remix durante la temporada navideña, el CTO quedó convencido de sus beneficios. Nuestra aplicación no es un monorepo, sino una carpeta única que contiene todo el código del frontend.

Construimos una prueba de concepto original con enrutadores de React configurados por Rails en tu ruta, y luego necesitábamos pasar a algo mejor. En ese momento, Remix todavía era de pago. Mi CTO no estaba convencido de usarlo porque era de pago, lo que significa que no todos lo conocerían. Sería más difícil contratar a alguien que conozca el framework. Comenzamos a usar Next por eso. Contribuí, uno de mis compañeros de trabajo es uno de los autores originales de NextJS. Comenzamos con Next, luego decidimos migrar a Remix porque comenzamos a tener problemas con el rendimiento de la aplicación. Las páginas de inicio del frontend eran geniales, pero lo que estás en la parte de la aplicación no es tan bueno, especialmente si no usas la mayoría de las cosas del lado del cliente, y eso fue lo que convenció al CTO de probar Remix. Lo probó en la semana entre Navidad y Año Nuevo. Después de eso, regresó de Año Nuevo y básicamente me dijo, sí, Remix es genial. Esta es mi lista de cosas. Aunque me gusta, vamos a migrar a nuestro código, para hacerlo. Es como si no quisieran cambiar a Remix, solo muéstraselo, haz que lo prueben, ¿verdad? Sí, creo que esa es la mejor manera de convencer a alguien de usarlo. Solo pruébalo, muéstralo. Genial, ¿tu aplicación es un monorepo? No es un monorepo, bueno, tenemos un monorepo, pero mi aplicación tiene el frontend en una carpeta que tiene todo del frontend. No se comparte con otros.

Monorepo Importing and Team Size

Short description:

En cuanto al monorepo, no hemos tenido dificultades para importar paquetes de componentes locales en Remix. Tenemos todo el código en la misma aplicación. Tenemos un equipo bastante pequeño de 8 personas trabajando en la base de código migrada. Es fácil convencer a las personas de migrar usando sus propios términos y expresándolo de manera diferente. Remix es fácil de aprender ya que utiliza la plataforma web y JavaScript. Contratar a alguien para trabajar en Remix es más fácil que contratar a alguien para otros frameworks.

partes del monorepo, porque son otros lenguajes. Bueno, tenemos una pregunta que está relacionada con el monorepo, así que si no lo sabes, no te preocupes, pero solo quería hacerla por si acaso. ¿Has tenido dificultades para importar paquetes de componentes locales en Remix en un entorno de monorepo? Sí, no lo hemos intentado, simplemente tenemos todo el código en la misma aplicación. Sí, genial. Así que tampoco tengo experiencia con eso.

De acuerdo, hagamos una última pregunta de Adrian. ¿Cuántas personas están trabajando en la base de código que migraron? Déjame contar. Tenemos 1, 2, 3, 4, 5, 6, 7, 8 personas. Genial. Es un equipo bastante pequeño, ¿verdad? Es bastante fácil convencer a las personas. Y creo que eso es algo que siempre he dicho, como, si estás hablando con un interesado o alguien que no es desarrollador sobre la migración, algo así, quieres asegurarte de usar sus términos y expresarlo de diferentes maneras a como lo harías si estuvieras hablando con un desarrollador. Así que creo que eso es otra cosa a tener en cuenta si estás tratando de convencer a tu empresa de migrar. Sí, además, cuando comenzamos, éramos cuatro personas. Contratamos al resto después de que comenzamos la migración. Y luego Remix, súper rápido. Uno de ellos lo aprendió para la entrevista en una semana, como una semana y dos días, algo así. Ese es otro gran punto, que Remix no tiene muchas cosas específicas de Remix, y utiliza la plataforma web. Así que realmente solo estás aprendiendo JavaScript en su mayor parte. Y React. Creo que eso hace que sea más fácil contratar a alguien para trabajar en Remix que contratar a alguien para trabajar en cualquier otra cosa. No necesitas aprender demasiado, solo aprendes sobre la web en sí misma. Sí, genial. Bueno, creo que eso es todo el tiempo que tenemos para preguntas. Muchas gracias por responder, Sergio, y gracias por unirte hoy. Gracias. Muy bien. Nos vemos.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Advanced Conference 2021React Advanced Conference 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Humans are natural problem solvers and we're good enough at it that we've survived over the centuries and become the dominant species of the planet. Because we're so good at it, we sometimes become problem seekers too–looking for problems we can solve. Those who most successfully accomplish their goals are the problem eliminators. Let's talk about the distinction between solving and eliminating problems with examples from inside and outside the coding world.
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
Do you have a large product built by many teams? Are you struggling to release often? Did your frontend turn into a massive unmaintainable monolith? If, like me, you’ve answered yes to any of those questions, this talk is for you! I’ll show you exactly how you can build a micro frontend architecture with Remix to solve those challenges.
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
Remix is a web framework that gives you the simple mental model of a Multi-Page App (MPA) but the power and capabilities of a Single-Page App (SPA). One of the big challenges of SPAs is network management resulting in a great deal of indirection and buggy code. This is especially noticeable in application state which Remix completely eliminates, but it's also an issue in individual components that communicate with a single-purpose backend endpoint (like a combobox search for example).
In this talk, Kent will demonstrate how Remix enables you to build complex UI components that are connected to a backend in the simplest and most powerful way you've ever seen. Leaving you time to chill with your family or whatever else you do for fun.
React Advanced Conference 2022React Advanced Conference 2022
29 min
Understanding React’s Fiber Architecture
Top Content
We've heard a lot about React's Fiber Architecture, but it feels like few of us understand it in depth (or have the time to). In this talk, Tejas will go over his best attempt at understanding Fiber (reviewed by other experts), and present it in an 'explain-like-I'm-five years old' way.
JSNation Live 2021JSNation Live 2021
29 min
Making JavaScript on WebAssembly Fast
Top Content
JavaScript in the browser runs many times faster than it did two decades ago. And that happened because the browser vendors spent that time working on intensive performance optimizations in their JavaScript engines.Because of this optimization work, JavaScript is now running in many places besides the browser. But there are still some environments where the JS engines can’t apply those optimizations in the right way to make things fast.We’re working to solve this, beginning a whole new wave of JavaScript optimization work. We’re improving JavaScript performance for entirely different environments, where different rules apply. And this is possible because of WebAssembly. In this talk, I'll explain how this all works and what's coming next.

Workshops on related topic

React Summit 2022React Summit 2022
136 min
Remix Fundamentals
Top Content
Featured WorkshopFree
Building modern web applications is riddled with complexity And that's only if you bother to deal with the problems
Tired of wiring up onSubmit to backend APIs and making sure your client-side cache stays up-to-date? Wouldn't it be cool to be able to use the global nature of CSS to your benefit, rather than find tools or conventions to avoid or work around it? And how would you like nested layouts with intelligent and performance optimized data management that just works™?
Remix solves some of these problems, and completely eliminates the rest. You don't even have to think about server cache management or global CSS namespace clashes. It's not that Remix has APIs to avoid these problems, they simply don't exist when you're using Remix. Oh, and you don't need that huge complex graphql client when you're using Remix. They've got you covered. Ready to build faster apps faster?
At the end of this workshop, you'll know how to:- Create Remix Routes- Style Remix applications- Load data in Remix loaders- Mutate data with forms and actions
DevOps.js Conf 2024DevOps.js Conf 2024
163 min
AI on Demand: Serverless AI
Featured WorkshopFree
In this workshop, we discuss the merits of serverless architecture and how it can be applied to the AI space. We'll explore options around building serverless RAG applications for a more lambda-esque approach to AI. Next, we'll get hands on and build a sample CRUD app that allows you to store information and query it using an LLM with Workers AI, Vectorize, D1, and Cloudflare Workers.
React Summit 2023React Summit 2023
106 min
Back to the Roots With Remix
Featured Workshop
The modern web would be different without rich client-side applications supported by powerful frameworks: React, Angular, Vue, Lit, and many others. These frameworks rely on client-side JavaScript, which is their core. However, there are other approaches to rendering. One of them (quite old, by the way) is server-side rendering entirely without JavaScript. Let's find out if this is a good idea and how Remix can help us with it?
Prerequisites- Good understanding of JavaScript or TypeScript- It would help to have experience with React, Redux, Node.js and writing FrontEnd and BackEnd applications- Preinstall Node.js, npm- We prefer to use VSCode, but also cloud IDEs such as codesandbox (other IDEs are also ok)
Remix Conf Europe 2022Remix Conf Europe 2022
195 min
How to Solve Real-World Problems with Remix
Featured Workshop
- Errors? How to render and log your server and client errorsa - When to return errors vs throwb - Setup logging service like Sentry, LogRocket, and Bugsnag- Forms? How to validate and handle multi-page formsa - Use zod to validate form data in your actionb - Step through multi-page forms without losing data- Stuck? How to patch bugs or missing features in Remix so you can move ona - Use patch-package to quickly fix your Remix installb - Show tool for managing multiple patches and cherry-pick open PRs- Users? How to handle multi-tenant apps with Prismaa - Determine tenant by host or by userb - Multiple database or single database/multiple schemasc - Ensures tenant data always separate from others
Remix Conf Europe 2022Remix Conf Europe 2022
156 min
Build and Launch a personal blog using Remix and Vercel
Featured Workshop
In this workshop we will learn how to build a personal blog from scratch using Remix, TailwindCSS. The blog will be hosted on Vercel and all the content will be dynamically served from a separate GitHub repository. We will be using HTTP Caching for the blog posts.
What we want to achieve at the end of the workshop is to have a list of our blog posts displayed on the deployed version of the website, the ability to filter them and to read them individually.
Table of contents: - Setup a Remix Project with a predefined stack- Install additional dependencies- Read content from GiHub- Display Content from GitHub- Parse the content and load it within our app using mdx-bundler- Create separate blog post page to have them displayed standalone- Add filters on the initial list of blog posts
React Day Berlin 2022React Day Berlin 2022
86 min
Using CodeMirror to Build a JavaScript Editor with Linting and AutoComplete
Top Content
WorkshopFree
Using a library might seem easy at first glance, but how do you choose the right library? How do you upgrade an existing one? And how do you wade through the documentation to find what you want?
In this workshop, we’ll discuss all these finer points while going through a general example of building a code editor using CodeMirror in React. All while sharing some of the nuances our team learned about using this library and some problems we encountered.