Video Summary and Transcription
RemixConf EU discutió los componentes de full stack y sus beneficios, como la unión del backend y la interfaz de usuario en el mismo archivo. La charla demostró la implementación de un cuadro combinado con funcionalidad de búsqueda utilizando Remix y la biblioteca Downshift. También destacó la facilidad de crear rutas de recursos en Remix y la importancia de la organización y mantenibilidad del código en los componentes de full stack. El orador expresó su gratitud hacia la audiencia y discutió el futuro de Remix, incluyendo su adquisición por Shopify y el potencial para la colaboración con Hydrogen.
1. Introducción a los Componentes de Full Stack
Estoy emocionado por RemixConf EU y hablar sobre los componentes de full stack. Estoy trabajando en Epicweb.dev, mi cosa a tiempo completo ahora. Esta charla es una demostración de componentes que incluyen código de UI y del lado del servidor. Hablaremos de Remix, nuestro marco de trabajo de full stack favorito.
¿Qué pasa amigos de Remix? Estoy muy emocionado por RemixConf EU y estoy realmente emocionado de estar hablando con todos ustedes sobre los componentes de full stack, así que vamos a hablar sobre llevar la colocación al siguiente nivel.
Así que una cosa de la que quería hablar rápidamente es que estoy trabajando en Epicweb.dev, si aún no lo has visto definitivamente échale un vistazo. Es mi cosa a tiempo completo ahora, es increíble. Y todas mis diapositivas y todo para esta charla están en mi GitHub por lo que puedes echar un vistazo a eso allí.
Así que esta charla va a ser una demostración de componentes que incluyen tanto el code de la UI como un code del lado del servidor y vamos a estar haciendo mucho código y así que sí, abróchate el cinturón. Vamos a estar hablando de Remix, por supuesto nuestro UI framework favorito. Bueno, marco de trabajo de full stack, no solo UI y eso es parte de lo que se trata esta charla.
2. Explorando las Características de Remix
Remix nos permite unir el backend y la UI en el mismo archivo. Podemos construir UIs que no están centradas en la URL, como el botón de 'me gusta' de Twitter. Vamos a demostrar un cuadro combinado que realiza una búsqueda. Tenemos una aplicación en funcionamiento con una ruta para buscar clientes. Podemos exportar un componente que consume el cargador. Estamos utilizando la biblioteca Downshift para la experiencia del cuadro combinado.
Así que Remix nos permitió unir el backend y la UI de una manera que nunca se había hecho antes con el cargador y la acción y nuestra UI todo en el mismo archivo. Y esta es una demostración bastante simple de cómo funciona desde una perspectiva de ruta. Así que tenemos nuestra ruta de proyectos y aquí tenemos nuestro cargador para cargar esos proyectos y tenemos nuestro formulario para agregar nuevos proyectos y la pieza de backend para esa mutación.
Pero a veces tenemos UIs que no son tan centradas en la URL, por ejemplo el botón de 'me gusta' de Twitter, cuando hago clic en ese botón de 'me gusta' eso no me va a llevar a otro lugar, no solo lo renderizo en una página especial que tiene una ruta específica, renderizo el botón de 'me gusta' para cada uno de los tweets que están en la página y eso no funciona muy bien como algo que te gustaría pegar en un cargador o una acción para una ruta particular necesariamente y aquí hay otro ejemplo de un cuadro combinado que está haciendo una búsqueda y esto es lo que realmente vamos a estar demostrando hoy.
Así que, tengo una implementación de esta aplicación aquí mismo, no estamos renderizando el cuadro combinado todavía porque vamos a construirlo juntos y conectarlo al backend y va a ser genial. Así que, eso es todo. Es hora de la demo. Así que, lo primero es que tenemos esta aplicación en funcionamiento aquí mismo, estamos en la versión 01.b4 de la aplicación y estamos en el directorio de la aplicación bajo rutas y bajo este directorio de recursos es donde encontraremos a los clientes. Así que, vamos a tener esta ruta para slash recursos slash clientes y esa va a ser la ruta de la API que vamos a estar usando para ir a buscar un montón de clientes.
Ahora, una cosa realmente genial sobre Remix es que si no tienes una exportación por defecto de tu módulo, Remix tratará tu módulo como un recurso. Y así, lo que queremos decir con eso específicamente es que puedo decir exportar una función asíncrona, vaya, una función, vamos, ahí, llamada cargador y aquí voy a devolver JSON y ese JSON en realidad va a venir de Remix run node y diremos hola mundo. Y si guardo eso y vengo aquí, puedo ir a recursos, clientes y voy a obtener hola mundo. Ahora, no hay nada especial en el directorio de recursos aparte del hecho de que mi editor parece que le gusta darle un icono especial, pero no hay nada especial en esto. Podemos llamar a esto como queramos y resulta que la forma en que me gusta que funcione mi URL para esto es tener un slash recursos y eso es todo. Así que donde quiera que queramos que sea esa URL, ahí es donde va a estar el archivo. Así que al tener una exportación de cargador pero sin exportación por defecto, esta es solo una solicitud regular para como una solicitud de API. Así que con eso en su lugar, ahora podemos construir algo de UI que interactúa directamente con este cargador que hace solicitudes de búsqueda. Pero lo que es realmente genial de Remix es que en realidad podemos añadir un montón de otras exportaciones a esto también. Podemos exportar const koala equals Kodi, como no importa. Podemos hacer lo que queramos aquí y Remix lo ignorará en sus construcciones. Así que lo que eso significa es que en realidad podemos exportar un componente aquí que consume este cargador y eso es exactamente lo que vamos a hacer. Y porque sé que probablemente no te importa verme escribir un montón de JSX, en realidad he escrito todo el material de JSX allí. Así que aquí está nuestro cargador, es justo lo que teníamos antes, pero luego tenemos un montón de otras cosas de JSX aquí que, como dije, probablemente no te importa verme hacer todo eso. Así que saltándonos la parte de JSX, la parte más importante e interesante aquí es que estamos usando esto use combo box, que es un gancho de Downshift. Downshift es una biblioteca que construí hace años cuando estaba en PayPal, y es para hacer esta experiencia de cuadro combinado para nosotros. Y todo lo que necesitamos hacer es proporcionarle los elementos y podemos responder a los cambios de valor de entrada a medida que el usuario está escribiendo. Así que eso es perfecto. Eso es exactamente las dos cosas que necesitamos. Y con eso estamos exportando este cuadro combinado, pero todavía somos solo una ruta de recurso. No hay nada especial pasando aquí.
3. Implementando Endpoint y Consultando Clientes
Esto simplemente está golpeando un endpoint y obteniendo la respuesta. Vamos a desarrollar el cargador y requerir autenticación. Obtendremos la URL y la consulta de la solicitud. Buscar clientes usando Prisma y SQLite. Enviar los clientes coincidentes en la respuesta.
Esto es literalmente solo golpear un endpoint y obtener la respuesta que enviamos. Así que vamos a hacer un par de cosas con este endpoint. Así que vamos a desarrollar este cargador.
Por un lado, personalmente no quiero que las personas puedan golpear este endpoint si no están autenticadas. Así que vamos a decir, Requerir Usuario. Y pasaremos la solicitud. Ahora obtenemos esa solicitud en nuestro cargador, por supuesto, así que pasaremos esa solicitud. Usaremos LoaderArgs. Ahí vamos.
Y con eso, ahora, todavía puedo hacer una solicitud a esto, pero si voy en modo incógnito, voy a ser redirigido al inicio de sesión. Así que eso es bueno. Recuerda, todos tus cargadores son básicamente endpoints de API de todos modos. Cualquiera podría hacer curl a esa URL y obtener acceso a todo lo que tienes en esa URL. Así que necesitas proteger tus datos de cargador, y así es como vamos a hacerlo aquí.
Entonces, lo siguiente es, voy a obtener la URL de la solicitud.URL. Convertir esto en un objeto URL para que pueda obtener la consulta de URL search-params.get. Y haremos una consulta de palabra completa aquí. Y queremos que la consulta sea, en este caso, o una cadena o nula. Vamos a establecer por defecto eso a una cadena. Así que siempre va a ser una cadena. Así que ahora puedo hacer buscar clientes.
Y esto se implementa usando Prisma y SQLite es cómo se configura esto. Pero esta búsqueda de clientes podría ser una implementación que hace una solicitud de búsqueda a otro servicio downstream o como un backend de Rails o PHP, o lo que sea. Esa parte no es importante. Solo el hecho de que tenemos algún mecanismo para enviar esta consulta a donde vamos a realmente consultar a los clientes. Así que pasaremos esta consulta y obtendremos nuestros clientes. Estos son los clientes coincidentes de vuelta. Y luego con eso, enviaremos eso en nuestra respuesta. Así que ahora si golpeo eso, no voy a obtener nada. Si digo, consulta S, entonces todavía no voy a obtener nada porque estropeé algo.
4. Implementando el Buscador de Clientes
Esta es la consulta correcta. Vamos a usar los parámetros de búsqueda de URL. Olvidamos hacer await, pero ahora podemos obtener los clientes y consultar los específicos. La salsa especial es nuestro useFetcher, que nos conecta con la UI. Implementamos el Buscador de Clientes con seguridad de tipo.
Entonces no, esa es la consulta correcta y consulta aquí y consulta allí. Oh, esto no es bueno. Entonces vamos a los parámetros de búsqueda de URL. Oh, rayos. Voy a tener que empezar de nuevo. Oh, sé lo que es. No voy a empezar de nuevo. Olvidé hacer await. Qué tonto soy.
Entonces ahora vamos a obtener los clientes. Ahí vamos. Vale. Entonces tenemos todos nuestros clientes allí, luego podemos consultar los específicos. Y podemos obtener un array de todos los clientes que coinciden. Así que eso es exactamente lo que estamos buscando para la ruta de la API.
Ahora aquí está la salsa especial. Esto es lo que realmente nos va a conectar con la pieza de la UI, es nuestro useFetcher. Así que Cody el Koala, hola. Aquí está Cody. Cody nos va a decir que necesitamos implementar Fetcher aquí. Entonces vamos a decir Fetcher, o lo llamaremos Buscador de Clientes. Puedes llamarlo como quieras. Realmente no importa. Y diremos useFetcher aquí mismo. Y luego para obtener los data con los que este Fetcher va a interactuar para ser completamente tipado, voy a decir typeof loader. Así que ahí está mi loader. Obtengo type safety para mi Buscador de Clientes. Y ese Buscador de Clientes va a tener una propiedad de data en él. Y si esa propiedad de data existe, puede que no. Porque en la renderización inicial, no estamos llamando a este loader desde el principio.
5. Manejo de Datos Indefinidos en TypeScript
Lo estamos llamando cuando el usuario está buscando, ¿verdad? Si no hay datos, entonces eso es indefinido. Si los hay, tendremos clientes. Así que nuestros clientes serán un array. Ahora TypeScript está contento, y nuestro cliente seleccionado tiene el tipo correcto.
Lo estamos llamando cuando el usuario está buscando, ¿verdad? Y así, si no hay data, entonces eso va a ser indefinido. Pero si hay, entonces vamos a tener clientes. Así que tendremos data Operador Elvis Clientes. Y si eso no existe, entonces tendremos a esos clientes como un array vacío. Y con solo ese cambio, ahora TypeScript está mucho más contento. Porque esta definición de tipo aquí, nuestros clientes van a ser un array de clientes. Y ahora este tipo es correcto. Y así, nuestro cliente seleccionado va a tener un tipo correcto. Y el tipo que pasamos a use combo box.
6. Realizando la Solicitud Fetch
Necesitamos hacer una solicitud fetch cada vez que cambia el valor de entrada. Downshift proporciona una API para detectar estos cambios. El Buscador de Clientes Search tiene opciones para hacer la solicitud. Usaremos la opción de enviar, que facilita la serialización de los parámetros de consulta. Manejaremos el caso cuando la consulta es indefinida asignando una cadena vacía.
Entonces, es realmente genial poder tener una completa type safety a través de la red para un componente que se va a utilizar en toda la aplicación. ¿Quién sabe dónde se usa? Así que la última parte de esto es realmente hacer la solicitud. Y para que realmente hagamos esta solicitud fetch, solo queremos hacer una solicitud cada vez que el valor de entrada cambia y Downshift nos proporciona esta API para saber cuándo cambia el valor de entrada. Y entonces lo que dirá es el Buscador de Clientes Search. Y hay un par de opciones aquí. Tenemos .form, que podríamos usar si esto fuera un envío explícito que el usuario está haciendo clic en un botón de enviar. Ese no es el caso para nosotros. Esta es una mutación imperativa o una consulta imperativa que necesitamos hacer como resultado de algunas otras interacciones del usuario. Así que no podemos usar form. También está load, que podemos usar para hacer una solicitud GET con parámetros de consulta, pero tenemos que serializarlos nosotros mismos. Así que no quiero hacer load, voy a hacer submit solo porque esto facilita mucho la serialización de esos parámetros de consulta. Y en realidad, GitHub Copilot está bastante cerca aquí. Aquí se está quejando porque la consulta solo puede ser una cadena, no puede ser asignada indefinida, un valor de entrada en los cambios que se nos dieron es opcional. Puede que no esté allí. Así que solo añadiremos, olvido cómo se llama esa sintaxis, coerción o algo, algo allí. Si int value es nulo o indefinido, entonces terminaremos con una cadena vacía.
7. Añadiendo el Método Get y Renderizando el Componente
Implementamos el método como un get, pero podría ser una acción. La URL de la acción es para el cargador dentro de resources/customers.tsx. Podemos usar este componente en cualquier lugar de nuestra aplicación y permanecerá conectado al cargador. Lo usaremos en la nueva ruta de facturas de ventas para elegir un cliente para una nueva factura. Generalmente no se recomienda importar desde el directorio de rutas, pero esta es una excepción. La funcionalidad actualmente funciona, y podemos arreglar el spinner.
Ahora, la última pieza que necesitamos agregar a esto es que necesitamos un método de get, o get en minúsculas aquí. Y eso es así porque hemos implementado esto como un cargador. Ahora, en realidad podríamos implementar esto como una acción y tener nuestro método que sea realmente cualquier cosa pero get, como un post o un put o algo así, pero estoy contento con que esto sea un get. Y luego, um, y como para los endpoints de consulta, normalmente tiene más sentido ser un get, pero sí, tú haces lo que quieras.
Lo genial es que no tienes que saltar a 30 archivos diferentes o múltiples repositorios para hacer este cambio, puedes simplemente un día decidir, sabes qué, quiero hacer esto como una acción en su lugar y simplemente cambiarlo aquí mismo en el mismo archivo, lo cual creo que es genial.
Vale. Y luego lo último es la acción. Ahora, esta acción es la URL que va a ser golpeada con esta consulta. Y la URL es la URL para este cargador, que ya hemos establecido que está dentro de los recursos, clientes, TSX. Así que vamos a decir /resources, /customers. Vale. Y eso es todo, hemos terminado esta característica. Y funciona totalmente. Pero necesitamos renderizar este componente. Y esta es la parte genial. Así que hasta ahora, esto se siente un poco como tu típica ruta remix y todo porque tienes tu cargador, tienes tu tipo de cargador, como todo se siente muy similar a lo que estás acostumbrado a construir en una ruta remix. Pero lo genial es que podemos usar este componente en cualquier lugar de nuestra aplicación y permanecerá conectado a este cargador de fondo. Así que en particular, la parte de la aplicación en la que queremos usarlo está dentro de nuestras ventas facturas nuevas cuando estamos creando una nueva factura para que podamos elegir qué cliente queremos. Y así, si bajamos aquí, ya tenemos a Cody ayudándonos con las propiedades que necesitamos pasar y todo. Así que tenemos nuestro combo box de clientes, que vamos a importar de las rutas, recursos, clientes. Así que normalmente, no recomiendo hacer ninguna importación desde el directorio de rutas. En general, creo que no es una forma realmente segura de hacer las cosas. Pero esta es una excepción que creo que es totalmente legítima y es totalmente impresionante. Así que eso es todo lo que vamos a hacer en la pieza del combo box del cliente aquí en la nueva ruta. Y con eso en su lugar, si vuelvo aquí y voy a crear una nueva factura, entonces tengo mi combo box de clientes. Ahora, actualmente tenemos esto configurado para verdadero, y podemos arreglarlo aquí en un segundo. Pero lo genial es que esta funcionalidad actualmente funciona totalmente a medida que hago cambios y puedo seleccionar al cliente y todo eso. Así que eso es bastante genial. Tenemos un componente que está conectado a su backend y todo en un solo archivo. Así que lo último que quiero hacer es arreglar el spinner porque eso me está molestando.
8. Implementando Spinner y Conexión al Backend
El estado pendiente es determinado por el SearchCustomerFetcher.state. Si el estado no es inactivo, se muestra el spinner. Para evitar un destello del estado de carga, se añade un retraso utilizando el paquete useSpinDelay. Esto asegura una transición suave y proporciona un agradable estado pendiente para los usuarios. El componente puede ser renderizado en toda la aplicación, conectado al backend. También puede ser empaquetado como un paquete npm para una fácil integración con otros proyectos.
Y así, si bajamos aquí, tenemos nuestro show spinner, y nuestro estado pendiente va a venir de nuestro fetcher. Así que tendremos nuestro SearchCustomerFetcher.state. Y el estado puede ser inactivo, cargando, o enviando. Básicamente, si está cargando o enviando, sabemos que estamos en un estado pendiente. Normalmente, determino si estamos en un estado pendiente diciendo, ¿es el estado no inactivo? Si no es inactivo, entonces estamos pendientes.
Hay una sutil diferencia entre enviar y cargar, donde cargar va a obtener algunos data, enviar es cuando el usuario está enviando data. Pero en nuestro caso, creo que es razonable simplemente decir si el estado no es inactivo, entonces podemos mostrar el spinner.
Así que con eso en su lugar ahora, podemos ver que no hay estado de carga. Pero si observas cuidadosamente, podrías ver un destello del estado de carga, y eso no es genial. Así que hay un par de opciones aquí. Puedes añadir un retraso de transición o algo así. Pero el problema es que si la solicitud tarda como 50 milisegundos de cualquier retraso de transición que pongas, vas a obtener un destello del estado de carga. Es básicamente imposible evitarlo sin un poco de ayuda extra.
Así que básicamente lo que necesitamos es decir no muestres el estado de carga a menos que sepas... bueno, pongamos un retraso porque eso tiene sentido. Si está dentro de 100 milisegundos no muestres ningún estado de carga en absoluto. Pero si muestro algún estado de carga, entonces deberíamos mantener el spinner dando vueltas incluso si ha terminado. Así que mantén el spinner dando vueltas por otros 300 milisegundos o algo así sólo para que no tengamos un destello, porque es mucho mejor mostrarlo por más tiempo del que lo necesitas que simplemente mostrar un destello del estado de carga. Y hay un paquete construido específicamente para resolver este problema. Fue construido para mi sitio web por Stefan Meyer, quien ayudó con la implementación de mi sitio web. Y se llama useSpinDelay. Y lo pasaremos por ahí. Tiene unos buenos valores por defecto que mantendremos. Y con useSpinDelay del módulo de retraso de giro, ahora vamos a evitar ese destello del estado de carga. Y si tenemos una red 3G lenta, entonces vamos a obtener un agradable estado pendiente, que es exactamente lo que nuestros usuarios esperarían. Así que con eso en su lugar, estamos sólidos. Esto es realmente, realmente genial. Podrías renderizar este componente en toda la aplicación y estar seguro de que está conectado a su backend. Además de esto, podrías también empaquetar esto en un paquete npm y luego exponer sólo un par de cosas para que la gente vaya a la configuración de Remix, añada su opción de rutas aquí, y llamen a tus cosas para que puedas conectar la ruta para la ruta de la API. Y entonces pueden empezar a usar tu componente y está todo mágicamente conectado al backend, lo cual es bastante interesante. Y me encantaría ver a alguien intentar hacer eso.
9. Conclusión y Rutas de Recursos
Remix nos permite crear rutas de recursos simplemente teniendo una ruta sin exportación predeterminada. Podemos exportar cualquier cosa que nos guste siempre y cuando no sea una exportación predeterminada. Esta co-ubicación de código facilita el mantenimiento del software a largo plazo.
Así que con todo eso dicho, permíteme concluir con un par de pensamientos finales. En resumen, Remix nos permite crear rutas de recursos simplemente teniendo una ruta sin exportación predeterminada. Eso es lo que hace una ruta de recursos. Podemos exportar cualquier cosa que nos guste siempre y cuando no sea una exportación predeterminada. Así que otros componentes y utilidades que se integran directamente con la ruta de recursos. Y entonces no son solo componentes. Podrías hacer hooks, realmente podrías hacer cualquier cosa como un botón que enlaza a un generador de PDF y el cargador es como genera el PDF, lo que sea. Cualquier cosa que se vincule específicamente a este recurso. Y simplemente mantén esa co-ubicación y esa code co-ubicación facilita el mantenimiento del software a largo plazo. Es realmente, realmente genial y emocionante. Me encanta esto.
Agradecimiento del Orador y Característica Favorita de Remix
El orador expresa su gratitud hacia la audiencia y les agradece. Menciona estar emocionado de estar en RemixConf EU y ser parte de la comunidad. Hablan de su característica favorita de Remix, Mutations, y cómo simplifica la gestión del estado de la aplicación. El orador se refiere a una encuesta donde una de las características favoritas era Kent. Luego, el orador pasa a la primera pregunta sobre si los componentes de pila completa rompen la separación.
Así que lo último que quiero decirles a todos es que son inspiradores. Muchas gracias. Nos vemos.
Hola, muchas gracias por tenerme. Estoy súper emocionado de estar aquí. ¡RemixConf EU es genial! Eso es triste. Súper feliz de ser parte de esta community.
Sí, es increíble tenerte aquí y esa presentación fue excelente. Así que la primera pregunta antes de empezar es en realidad para ti. Y quería preguntar, ¿cuál es tu característica favorita de Remix? ¿Mi característica favorita de Remix? Elegí Mutations. Creo que la gestión del estado de la aplicación state management es la parte más difícil de construir una aplicación web en estos días. Y Remix hace que eso no sea un problema, completamente. Así que esa es mi característica favorita sin duda. Eso es genial. Cuando hicimos la encuesta en Slido, una de las características favoritas era Kent. Así que pensé que era bastante apropiado. Fue bastante impresionante. Así que empezaremos con las preguntas. Empezaremos con la primera. ¿Los componentes de pila completa rompen la separación? Oh, sí. Dios mío. Te hice tu pregunta. Olvidé completamente que la hicimos. Hicimos la pregunta de antemano que proporcionaste. ¿Ves lo emocionado que estoy de hablar contigo, Kent? Mejor recuerdo que también hay otras personas que quieren hacer preguntas. Pero antes de hacer eso, hiciste la pregunta, que era cuál de estos no es una exportación aceptada de Remix? Y tenías un par de opciones diferentes. Y parece que la mayoría de la gente eligió should revalidate. Fue como el 78%. Algunas personas pensaron que era handles. Algunas personas pensaron que era headers.
Componentes de Pila Completa y Separación de Preocupaciones
Should revalidate en Remix se llama una API inestable, y se llama should reload. El equipo de Remix está actualmente moviendo las APIs del enrutador React de nuevo a Remix. Y eventualmente, será should revalidate. Pero por ahora, es unstable should reload. Los componentes de pila completa rompen la separación tradicional de preocupaciones. JSX comenzó a romper la idea de no mezclar lógica con marcado. Las interfaces de usuario requieren lógica y diseño, por lo que la preocupación es la combinación de todas estas tecnologías. CSS y JS, Tailwind, y el backend son todos parte de la preocupación.
Y algunas personas pensaron que eran links. Entonces, ¿cuál es la respuesta correcta Kent? Sí. La mayoría de las personas lo acertaron. Esta es un poco una pregunta trampa porque should revalidate en Remix se llama una API inestable, y se llama should reload. Unstable should reload. Pero en react router versión 6.4, se llama should revalidate. Y ellos, el equipo de Remix, están actualmente moviendo las APIs del enrutador React de vuelta a Remix. Y eventualmente, será should revalidate. Pero por ahora, es unstable should reload.
Eso es genial. Y de nuevo, recuerden ir a Slido para participar en estas preguntas que vamos a hacer durante el show. Y eso fue un recordatorio para mí, por cierto. Y volvamos a las preguntas con Kent. Y vayamos a la primera. ¿No rompen los componentes de pila completa la separación de preocupaciones? Sí, sí. Esa es una buena pregunta. Entonces, hemos estado rompiendo la idea de la gente de lo que significa la separación de preocupaciones durante años. Comenzando principalmente, o al menos en la era moderna, comenzó con JSX. Y la gente vio JSX y dijo, no debería mezclar mi lógica con mi marcado. Simplemente no tiene sentido. Bueno, el hecho es que estamos trabajando en interfaces de usuario, y la lógica es una parte muy importante de lo que estás tratando de lograr. Entonces, para mí, esa es la preocupación. La preocupación es el botón de like de Twitter, o lo que sea que estés construyendo. El botón de like de Twitter es un buen ejemplo, porque no es solo la lógica detrás de si está activado o desactivado y qué hacer cuando se hace clic en el botón, sino que es también cómo se ve la cosa. Entonces, tenemos CSS. Eso también es parte de eso. Entonces, ahora la preocupación incluye las tres tecnologías. Entonces, ese fue mi argumento para CSS y JS, y ahora estoy en Tailwind, que es una especie de enfoque diferente a eso. Pero solo la co-ubicación de las preocupaciones que usa ese caso. Pero incluso eso no cubre completamente el caso de uso, ¿verdad? También está la parte del backend de eso.
Componentes Fullstack y Arquitectura de Islas
Los componentes Fullstack abrazan el hecho de que las cosas que cambian juntas deben permanecer juntas, redefiniendo la separación de preocupaciones. La idea surgió durante la masterclass avanzada de Remix para la Remix Conf. A Ryan inicialmente le gustó la idea, y ha ganado popularidad. Los componentes Fullstack no son lo mismo que la arquitectura de islas, ya que se centran en la organización y mantenibilidad del código en lugar de la optimización del rendimiento. Proporcionan un entorno cohesivo para colocar el código que debería vivir junto.
Entonces, los componentes Fullstack llevan esa idea más allá, y realmente, mi estrategia óptima de organización de code es que las cosas que cambian juntas deben permanecer juntas. Y entonces, si estás cambiando el code del backend cada vez que cambias el code del frontend, y viceversa, bueno, tal vez puedes poner esas cosas juntas. Y si estás cambiando dos cosas juntas frecuentemente, entonces tal vez son la misma preocupación. Y entonces, sí, no rompe la separación de preocupaciones. Acepta el hecho y tal vez redefine lo que significa la separación de preocupaciones en tu mente. Sí, no, genial. Y Michael Broomly se preguntaba si esto era un patrón algo que el equipo de Remix específicamente tenía la intención o más bien emergente, oh, vamos a probarlo tipo de cosa? Sí. Entonces, de donde vino para mí fue que estaba trabajando en la masterclass avanzada de Remix para la Remix Conf en los EE. UU. y estaba construyendo un combo box mostrando cómo usar use Fetcher y todo. De hecho, como el que hicimos hoy, el mismo ejemplo exacto. Y los tenía en varios... Así que tenía un recurso redondeado aquí y luego tenía mi componente allí y me preguntaba, me pregunto si podría simplemente... y luego, seguro, supongo que por qué no? Y se lo mostré a Ryan porque iba a co-presentar esa masterclass conmigo. Él dijo, no lo odio. Y déjame pensar en eso por un rato. Y luego finalmente decidió que realmente le gustaba. Me encanta. Y entonces, sí, definitivamente no es algo que el equipo de Remix haya pensado realmente. Pero estoy viendo esto y me encanta. Ahora, eso es genial. Eso es genial.
Otra pregunta que tenemos, KB dice, he estado escuchando el término arquitectura de islas recientemente de otros frameworks de JS. ¿Son estos componentes Fullstack como la versión de Remix de eso? No exactamente. La arquitectura de islas tiene mucho más que ver con lo que se hidrata y dónde. Y en las aplicaciones de Remix, todavía se hidrata todo el conjunto. Así que es un poco diferente. Podrías ser capaz de implementar una especie de arquitectura de islas de esta manera. Sí, la gente hace cosas salvajes con las rutas de recursos. Pero sí, esto es más, es menos acerca de pensar como una optimización de rendimiento, y más acerca de una optimización de mantenibilidad y colocando el code que debería vivir junto.
Componentes Full Stack y Publicación en NPM
Los componentes Full Stack permiten una excelente manera de desarrollar componentes que pueden aceptar props, hacer referencia al contexto y combinar el código de backend y frontend. Se pueden publicar en NPM creando un archivo de ruta y llamando a funciones en un módulo NPM o publicando una función para ser llamada en la configuración de REMIX. Hidratar rutas específicas en REMIX puede crear islas, pero puede que no se alinee completamente con el concepto de arquitectura de islas.
Definitivamente se siente como si estuvieras en una isla, porque quiero decir, tu componente puede aceptar props y todo. Puede hacer referencia al contexto y cosas así. Pero realmente se siente como si estuviera en su propia pequeña isla. Y tiene su backend y frontend y todo junto. Es simplemente una excelente manera de desarrollar esos tipos de componentes.
Genial, genial. Y otra pregunta. ¿Se pueden publicar los componentes Full Stack en NPM? Esa es una gran pregunta también. Entonces sí, pueden. Así que el desafío es, tienes un solo archivo. Y con REMIX, hay una convención de archivos. Entonces, ¿cómo haces, como si quisiera hacer un botón de Twitter que la gente pueda usar en todos sus diferentes sitios web, cómo lo haría como un componente de un solo archivo? Porque necesitamos tener un archivo en el directorio de rutas para una ruta de recurso. Bueno, eso no es completamente cierto porque en realidad puedes crear rutas de manera imperativa en la configuración de REMIX en tiempo de construcción. Hay una opción de rutas allí. Y entonces tienes dos opciones. Podrías hacer un archivo de ruta y luego simplemente llamar a funciones en un módulo NPM que maneja todo por ti y solo le dices cuál es la URL de la ruta de recurso. O podrías publicar una pequeña función que las personas se supone que deben llamar en su configuración de REMIX. Y entonces en la configuración de REMIX, decimos como, configura mi ruta de botón de Twitter. Y entonces de esa manera, el módulo de Twitter NPM sería capaz de saber cuál es la URL para la ruta de recurso, porque es responsable de crear esa ruta de recurso. Y luego puede hablar consigo mismo de esa manera. Así que no he visto a nadie hacer esto, pero creo que sería genial si alguien lo hiciera.
No, impresionante. Impresionante. Para seguir con la pregunta de la arquitectura de islas, ¿no podrías hidratar solo rutas específicas en REMIX para hacerlo islas? Entonces, sí, no lo haría. Sí, estoy seguro de que es posible. No es algo que haya probado. Pero, no llamaría a eso– Islas para mí es como muchas cosas en una sola página. Tenemos la idea de rutas anidadas, y entonces tal vez puedes tener una ruta anidada que esta es la única parte que está hidratada. No voy a decir que la arquitectura de islas no está en línea con lo que REMIX está tratando de hacer. No estoy completamente convencido de que– Aunque técnicamente, desde un punto de vista teóricamente técnico, es mejor ejecutar menos código.
Arquitectura de Islas y la Adecuación de REMIX
No estoy convencido de que la arquitectura de islas siempre sea lo correcto. Uso REMIX para todo. Hay muy pocos proyectos para los cuales REMIX no es adecuado. REMIX aún no tiene HMR, pero el equipo está trabajando en ello. Comenzar con REMIX te permite adaptarte a los cambios de requisitos mejor que cualquier otra cosa. Que REMIX sea parte de Shopify es emocionante, ya que proporciona estabilidad y financiación para el marco de trabajo.
Pero en términos prácticos, no estoy convencido de que la arquitectura de islas siempre sea lo correcto. E incluso necesario para la mayoría de las aplicaciones. Y por eso no he pasado mucho tiempo pensando en o trabajando en eso yo mismo. Pero estoy convencido de que podrías implementar una arquitectura de islas con REMIX pero sí, no me he molestado en intentarlo.
Sí, no, gracias por eso. Esta es una pregunta que quiero hacer porque sé que hay mucha gente que aún no ha probado REMIX. Entonces, ¿hay algún proyecto para el que no usarías REMIX o cuál es tu pensamiento al respecto?
Sí, no hay proyectos para los que no usaría REMIX. Uso REMIX para todo. Así que hay muy pocos proyectos para los que REMIX no es adecuado. He hablado con algunos equipos que son como, bueno, simplemente no podemos vivir sin HMR. Es como, bueno, quiero decir, está bien. REMIX aún no tiene HMR. Eventualmente, lo tendremos, pero aún no. Las cosas son un poco únicas porque REMIX es tan centrado en el servidor, como ¿cómo haces HMR con el servidor y cosas así, pero estoy convencido de que el equipo eventualmente va a encontrar una solución para eso. Pero como casi cualquier otra cosa que pueda pensar, como piensas, está bien, ¿qué pasa si tengo una sola página? Es un juego, está usando el almacenamiento local para todo. ¿Por qué usaría REMIX para eso? Quiero decir, sí, no vas a aprovechar el enrutamiento anidado, ese tipo de cosas. No estás aprovechando los cargadores necesariamente. Pero ¿qué más vas a usar que vaya a ser mejor? Como, ¿Veep te servirá mejor? Realmente no. Es como si todos estuviéramos en el mismo campo de juego. Y lo genial de empezar con REMIX es que eventualmente cuando decidas, oh, hombre, este juego es wordle y estoy a punto de vender a esta gran empresa o lo que sea, y necesitamos persistencia de data y ya sabes... Bueno, simplemente actualizas a eso porque lo construiste con REMIX desde el principio. Y por eso me cuesta ver situaciones donde REMIX no sea un gran punto de partida porque te permite adaptarte a los cambios de requisitos mejor que cualquier otra cosa que haya visto.
Genial. Genial. Y aquí hay otra gran pregunta. ¿Cómo crees que el hecho de que REMIX forme parte de Shopify afectará al marco de trabajo? Oh, Dios mío. Estoy muy, muy emocionado con esta cosa de Shopify. Imagina por un momento que REMIX no se hubiera vendido a Shopify, REMIX estaría, seguiría estando bien. Como que hubiéramos seguido trabajando bien durante un año y medio más o así con la financiación que habíamos recibido originalmente con el número de empleados que teníamos. Así que habría estado bien pero el problema es que eventualmente el equipo de REMIX tendría que encontrar una manera de ganar dinero.
La adquisición de Shopify y el futuro de REMIX
La adquisición de REMIX por parte de Shopify permite a los desarrolladores centrarse únicamente en el desarrollo del marco de trabajo sin distracciones. Esta asociación asegura que la versión dos de REMIX se lanzará antes, beneficiando a la comunidad. Los requisitos únicos de Shopify los convierten en una empresa de adquisición ideal, proporcionando una base sólida para un marco de trabajo. Su colaboración promete casos de uso emocionantes y un futuro positivo para REMIX.
Y lo que todo esto significa es que estos increíbles desarrolladores que están desarrollando este framework para nosotros se distraerían con otras cosas que no están relacionadas con lo que es el framework. Y entonces Shopify simplemente dice, hey, sigue trabajando en lo que estás haciendo, estás haciendo un gran trabajo con eso y nosotros nos encargaremos de la parte monetaria. Y estoy encantado de que Ryan y Michael en particular no tengan que preocuparse por la parte de ganar dinero y simplemente continúen trabajando en este framework para nosotros. Creo que estoy convencido de que obtendremos la versión dos de REMIX mucho antes de lo que lo habríamos hecho si hubieran tenido que empezar a pensar en ganar dinero. Así que estoy emocionado y de todas las empresas que podrían adquirir REMIX, creo que Shopify es simplemente tan buena como empresa de adquisición porque tienen algunos de los requisitos más interesantes que no creo que sean generalmente aplicables a todos pero definitivamente es una muy buena base o un denominador común para lo que la gente necesita de un framework. Estoy realmente emocionado por los casos de uso que Shopify aportará a REMIX. Y creo, y han sido realmente increíbles como empresa también. Así que creo que van a ser muy buenos administradores de la web y un lugar realmente genial para que REMIX pase el rato.
El amor del orador por REMIX y el apoyo de Shopify
Me enamoré de REMIX al instante. El apoyo de Shopify aumenta la confianza y la adopción. REMIX es mi opción predilecta para proyectos personales, permitiendo un desarrollo más rápido.
Sí, no, eso es realmente, realmente impresionante. Tan pronto como probé REMIX, me enamoré de él al instante. Y muchas veces cuando muestro REMIX a otros, dicen, vaya, esta es una forma realmente genial de hacerlo. Y creo que tener una empresa como Shopify respaldando a REMIX es enorme porque da más confianza para que alguien diga, hey, esto está respaldado por Shopify, déjame revisar esto y aumentará la tasa de adaptación. Pero para mí, como dije, para todos mis proyectos personales, REMIX ha sido mi forma preferida de hacer las cosas. Y me encuentro desarrollando cosas más rápido, lo cual es bastante impresionante.
Influencias de Hydrogen en REMIX
El equipo de REMIX discutió las influencias de Hydrogen hacia REMIX con Shopify. Compararon los componentes del servidor con las capacidades actuales de Remix y encontraron que Remix es un enfoque mejor. Shopify decidió incorporar al equipo de Remix. Es probable que el papel de Hydrogen implique más componentes de pila completa, como un carrito de compras configurable. El objetivo final aún no está claro, pero puede haber una pila de Hydrogen o una CLI especial. No se espera que los conceptos de Hydrogen se integren en Remix, ya que Remix ya tiene una funcionalidad similar. Sin embargo, los ingenieros de Shopify contribuirán al desarrollo de Remix.
Y supongo que otra pregunta que tengo, ¿crees que va a haber influencias de hydrogen hacia REMIX? Sí, de hecho, el equipo de REMIX, hablamos con Shopify hace meses, incluso antes de REMIXconf. Vinieron a Salt Lake, estábamos hablando de, ya sabes, potencialmente hacer lo que están haciendo ahora antes de que lanzaran hydrogen con los componentes del servidor. Y solo estábamos tratando de decir, oye, escucha, como los componentes del servidor aún no están realmente lanzados. Como no es una API estable ni nada. Como vas a lanzar sobre algo que no está terminado. Pero mira lo que tenemos ahora. Así que compara lo que los componentes del servidor te dan quizás en el futuro con lo que Remix te da hoy. Ahora, absolutamente. Y simplemente pensamos que este es un enfoque mejor. Y así, finalmente Shopify tomó eso en serio y decidió que realmente querían al equipo de Remix y nos trajeron o ya no estoy allí. Solo para que quede claro. Estoy a tiempo completo en Epic web, pero decidieron traer al equipo de Remix. Y creo que el papel de hydrogen será más componentes de pila completa. Tipo de situaciones, tendrán como un carrito de compras que traes y quizás configuras. Podría ser como, tenían la publicación de blog donde todavía estás usando hydrogen, pero estás importando cosas de Remix. Así que hay una especie de mezcla allí. No estoy seguro de cuál es el objetivo final de eso. Como, ¿instalas Remix? Y luego, o tal vez hay una pila de hydrogen algo así. Creo que probablemente tenga mucho sentido tener una pila de hydrogen. Espero que probablemente sea algo que salga de eso, ya sea técnicamente una pila o tal vez una CLI especial que el equipo de hydrogen invente. Pero en cuanto a los conceptos de hydrogen que entran en Remix, no veo nada de eso. No parece haber nada que hydrogen específicamente tuviera que Remix no tuviera ya fuera de cosas que son específicas de Shopify, como el carrito de compras y cosas así, que por supuesto no estarían bien colocadas dentro de un framework genérico como Remix. Pero ciertamente, hay muchos ingenieros realmente inteligentes en Shopify que absolutamente estarán ayudando a Remix de muchas maneras. Así que estoy esperando esa colaboración también.
Componentes de pila completa y gestión de estado
En Remix, no hay necesidad de bibliotecas de gestión de estado como Redux. El marco funciona sin JavaScript y abraza el concepto de mejora progresiva. Usar la gestión de estado de la aplicación obstaculizaría la mejora progresiva. Aunque técnicamente es posible usar Redux con Remix, no se recomienda ya que el marco no lo requiere.
No, eso es genial. Eso es genial. Y tenemos una pregunta de Peter Horn, ella pregunta, ¿se supone que los componentes de pila completa son reemplazos para las bibliotecas de state management, como Redux o complementos? Sí, en realidad, en Remix, realmente no se necesitan bibliotecas de state management, gestión de estado de la aplicación en absoluto. No hay gestión de estado de la aplicación. Eso se evidencia por el hecho de que funciona sin JavaScript, pero también es requerido por la idea de mejora progresiva. Entonces, si te enfocas en la mejora progresiva, entonces no puedes usar la gestión de estado de la aplicación. Si lo haces, entonces tu aplicación no mejora progresivamente, yo llamo a eso un error. Y entonces, aunque técnicamente puedes usar Redux y esas cosas con Remix, te aconsejo enérgicamente que no lo hagas por esa razón. Y entonces los componentes de pila completa no son como un reemplazo. Ciertamente podrían trabajar con esas cosas, pero sí, no me molestaría usarlas porque no las necesitas con Remix. Sí, no, eso tiene sentido. Veamos si tenemos algunas últimas preguntas finales aquí, que se acercan. Y entonces otra pregunta, ¿cómo crearía un componente similar al que mostraste, pero quería usar el cargador porque no debería haber interacción con el usuario y para beneficiarse de la renderización del servidor. Tengo un componente, adelante. Sí, esa es una gran pregunta. Entonces, si quieres renderizar en el servidor los data porque lo que estaba haciendo era después, ya sabes, después de la hidratación y todo. Entonces lo que podrías hacer es similar a lo que los Remix Docs dicen sobre los enlaces para componentes donde se exporta, el archivo de componente exporta los enlaces y luego cualquier ruta que lo use incluirá esos enlaces en su propia definición de enlaces. Entonces haces lo mismo para el cargador. No lo he hecho yo mismo, pero sí, si necesitas algo que se renderiza en el servidor, pero lo renderizas en muchos lugares diferentes entonces sí, la única forma de obtener data renderizados en el servidor es a través de un cargador en una ruta, no una ruta de recurso. Tiene que ser un cargador en una ruta y sí. Entonces, probablemente así es como abordaría eso si quiero hacer eso. Muchas gracias, Kent. Creo que ese fue todo el tiempo que tuvimos. Esa fue una charla increíble. Muchas gracias por estar aquí y hablaré contigo más tarde y vuelvo con Brittany. Gracias, nos vemos.
Comments