AAR: Wanthat.io, el no reinventar la rueda y threejs journey
Cómo publiqué una WebApp para conseguir threejsJourney
Hace unos años, antes de que los gameplays de YouTube se pusieran de moda, existía una manera muy chula de compartir en internet tus experiencias jugando a videojuegos: Los AAR, o After Action Report. Básicamente un fulano jugaba una partida a un juego, o todo una campaña, y luego publicaba en un foro un post completo novelando (o simplemente contando) lo que le había pasado.
Ejemplo de un AAR de Dwarf Fortress
Alrededor de 2010 yo era un fanático de estos relatos: Me permitían disfrutar de juegos que no podía, no tenía tiempo o me daba miedo jugar. Cuando la alpha de Minecraft empezó a hacerse popular adquirí una licencia y empecé a jugar al juego. Un día me atasqué con algo y, buscando guías por internet, dí con un gameplay en YouTube. Ese día murieron los AAR para mi.
Minecraft en 2010, cuando molaba
Desde entonces le he dedicado muchas horas a ver gameplays y es un formato que permite desconectar mucho mas que leer un relato en un foro. Pero si es cierto que no tienen ni una décima parte del encanto que tenían aquella relatos.
Volviendo al presente, a parte de un desarrollador de software profesional, también me jacto de ser un desarrollador indie de aplicaciones. Hace ahora casi dos años publiqué mi primer desarrollo completo de una webapp con una funcionalidad real: wanthat.io. Wanthat es un gestor de deseos con función social: una aplicación que te permite crear una lista de deseos y compartirla con tus amigos para que sepan qué regalarte en tu cumpleaños, por ejemplo.
Como estaba entusiasmado con lo que había hecho, quise compartirlo. Era finales de 2019 y franbosquet.com llevaba ya más de un año sin actualizar. Dudé que fuera a tener ninguna repercusión contarlo allí, ya que los parroquianos cada vez tenían menos actividad (debido a la falta de actualizaciones), así que opte por hacer un hilo en twitter. Y en un arranque de nostalgia, se me ocurrió adoptar el formato del AAR.
La idea era exponer lo que había hecho, lo que había aprendido y mis conclusiones. Entretener y enseñar algo a mis seguidores y, con suerte, conseguir algunos nuevos. O incluso nuevos usuarios para wanthat. Lo cierto es que el éxito fué discreto como mucho: Seguidores nuevos, dos. Usuarios, uno que la uso un rato y nunca más volvió. Pero me lo pasé muy bien haciéndolo y, al igual que el blog, quedo el hilo para la posteridad para yo mismo revisarlo cada cierto tiempo y hacer retrospectiva acerca de como evoluciono yo mismo.
AAR: Wanthat.io, el no reinventar la rueda y threejs journey
Como ahora quiero volver a darle vida al blog, creo que una buena manera es recuperar ese contenido que quedó un poco desamparado en twitter. Y de paso para traducirlo, ya que lo hice en Ingles en su momento y habrá gente que no lo lleve muy allá. Compartir mi opinión a día de hoy sobre las decisiones que tome durante aquel desarrollo.
Es una oportunidad para adoptar el nuevo modulo react-tweet que publico la gente de Vercel este verano. Permite integrar tweets en el blog, cosa que cuando lo programé no fuí capaz de hacer. De hecho algunos post antiguos del blog tenían tweets incrustados que he tuve que eliminar porque no funcionaban.
Introducción
How I published a WebApp to get #threejsJourney! Thread🧵
¡Cómo publiqué una WebApp para conseguir #threejsJourney! Hilo🧵
A month ago my girlfriend gave me the best possible Christmas present: #threejsJourney. It's a programming course to learn how to use #threejs
Hace un mes mi novia me hizo el mejor regalo de Navidad posible: #threejsJourney. Es un curso de programación para aprender a usar #threejs
#threejs is JS library that allows you to render 3D graphics in the browser without the need to deal with the low-level WEB GL api. The course is taught by @bruno_simon and it's simply AWESOME!
#threejs es una librería JS que permite renderizar gráficos 3D en el navegador sin necesidad de lidiar con la api WEB GL de bajo nivel. El curso lo imparte @bruno_simon y es sencillamente ¡IMPRESIONANTE!
Three caught my attention because some years ago I used to play with Unity. And I really miss tinkering with 3d graphics. But not C# or Unity itself, not at all. So one day I decided to investigate what I could really do with the browser on that behalf
Three me llamó la atención porque hace algunos años solía jugar con Unity. Y echo mucho de menos trastear con gráficos 3d. Pero no C# ni Unity en sí, para nada. Así que un día decidí investigar qué podía hacer realmente con el navegador en ese sentido
Amo bastante los videojuegos y me encanta la escena de desarrollo independiente. De hecho tengo dos juegos chorris publicados en itch.io de una Jam que organizó Brackeys si no recuerdo mal. Esa historia también da para un AAR. Pero la abstracción que es Unity siempre me ha frustrado sobre manera. Acostumbrado a programar para la web, donde tienes un control bastante granular de lo que está pasando, Unity me mete en un mundo de magia negra donde de cada tres cosas que pasan en pantalla, no entiendo dos. Sobre todo en tema de físicas. Y eso me frustra mucho y acabé aparcándolo por eso.
Pero por otro lado, Unity fue lo que me hizo recuperar la programación en un momento de mi vida en el que la tenía dejada bastante de lado y con el aprendí C#. Para poder odiarlo con razón, digo. Tampoco creo que sea peor que Unreal o Godot, simplemente que los motores comerciales de videojuegos son más de lo que me apetece masticar. En una nota de actualidad, sus directivos la acaban de liar bastante y han retratado a la empresa de una manera muy preocupante.
Por todo ello siempre le guardaré cariño a Unity, pero no lo volveré a tocar si puedo evitarlo.
And I was impressed. The limit is really set by your graphics card, so to a certain extent you have your hands free to develop games or interactive 3D experiences. With programmable shaders, real-time mesh transformations, post-processing... All in the browser. Amazing
Y me quedé impresionado. El límite lo pone realmente tu tarjeta gráfica, así que hasta cierto punto tienes las manos libres para desarrollar juegos o experiencias 3D interactivas. Con shaders programables, transformaciones de malla en tiempo real, post-procesado... Todo en el navegador. Increíble
Si no sabes de que va, mira los ejemplos en su web. Flipa con esta web de canon o esta de Lamborghini
So I got into it. The documentation is not very lazy-friendly. And im lazy. So I looked for step-by-step tutorials to get started with this. I found some on youtube, some cheap ones on coursera... But the impression I got from them was very poor
Así que me puse a ello. La documentación no es muy amigable para los perezosos. Y yo soy perezoso. Así que busqué tutoriales paso a paso para empezar con esto. Encontré algunos en Youtube, algunos baratos en Coursera... Pero la impresión que obtuve de ellos fue muy pobre
Until I came across the Mercedes-Benz of ThreeJs courses: threejs-journey.com. A lot of content, a teacher who really masters the library, a good format, an attractive website... This was what I was looking for. The problem: 95USD
Hasta que me topé con el Mercedes-Benz de los cursos ThreeJs: threejs-journey.com. Mucho contenido, un profesor que realmente domina la biblioteca, un buen formato, una web atractiva... Esto era lo que buscaba. El problema: 95USD
En esta primera serie de tweets doy un preámbulo sobre la historia que estoy a punto de contar: Cómo llegué a interesarme por Threejs y mi interés en el curso de Bruno Simon a ese respecto. Pero también mi problema con el mismo: Mi reticencia a gastar 95 dólares y luego no dedicarle el tiempo suficiente para ponerlo en valor o disfrutarlo.
Así que en la siguiente parte describo la pirueta moral y tecnológica que hube de hacer para obtener dicho curso sin gastarme un duro 🤣
Motivación para hacer Wanthat
Don't get me wrong: I have no problem with the price. It seems cheap to me in fact. The problem is ME with the courses: I buy them, I don't finish them
No me malinterpreten: no tengo ningún problema con el precio. De hecho, me parece barato. El problema lo tengo yo con los cursos: Los compro, no los termino...
So for a while now, I try not to buy courses. It's sad, but I know myself and if I'm not 100% hooked I end up dropping them. And lately between work, side projects and hobbies I don't have much free time to spare
Así que de un tiempo a esta parte intento no comprar cursos. Es triste, pero me conozco y si no estoy 100% enganchada acabo dejándolos. Y últimamente entre trabajo, proyectos paralelos y aficiones no tengo mucho tiempo libre que digamos
Poco antes de esto utilicé el presupuesto de formación de Taxfix (la empresa en la que trabajo) para comprar Advanced React & Graphql. El curso estaba muy bien, como todo lo que hace Wes Bos, pero por falta de tiempo y al perder interés en el tema (reconozcámoslo de una vez: GraphQL es un coñazo) lo acabé abandonando. Desde ese momento le cogí algo de "miedo" a comprar cursos, ya que al igual que todo lo demás los cojo con muchas ganas pero voy perdiendo el interés con el tiempo.
So the only way I could get the course without a guilty conscience was to get it as a gift. From who? Well, the person closest to me, to whom I could talk about it enough for her to decide to give it to me for Christmas: My girlfriend Cristina! 🥰🥰🥰🥰
Así que la única forma de conseguir el curso sin remordimientos de conciencia era que me lo regalaran. ¿De quién? Pues de la persona más cercana a mí, con la que pudiese hablar de ello lo suficiente como para que decidiera regalármelo por Navidad: ¡Mi novia Cristina! 🥰🥰🥰🥰
This all started in September. At first I told her about the existence of the course, that I was thinking on buying it, etc. But between then and Christmas it was going to be difficult for her to remember and she would probably end up giving me something else.... I needed a plan
Todo esto empezó en septiembre. Al principio le conté que existía el curso, que pensaba comprarlo, etc. Pero desde entonces a Navidad iba a ser difícil que se acordara y probablemente acabaría regalándome otra cosa.... Necesitaba un plan
Programación neurolinguística, manipulación, chantaje emocional... llámalo como quieras.
Toda la historia suena fatal, pero he de mencionar que normalmente nos hacíamos/hacemos regalos incluso más caros: Lo que quería (y de eso va esta historia) es que se gastara el dinero en lo que más feliz me iba a hacer, el curso de Bruno Simon, antes que en cualquier otra cosa.
Con Cristina me casé este 2023, por cierto 💑
As a developer, the solution was clear: I needed an app. A wishlist that users can check to have a clear idea of what to gift to a friend. That way she would give me exactly the gift I wanted
Como desarrollador, la solución estaba clara: necesitaba una aplicación. Una lista de deseos que los usuarios pudieran consultar para tener una idea clara de qué regalar a un amigo. Así me daría exactamente el regalo que quería
And at the same time I would have a tool to not be so overwhelmed when It comes to give a gift. I'm a disaster when it comes to giving gifts!
Y al mismo tiempo tendría una herramienta para no agobiarme tanto a la hora de hacer un regalo. ¡Soy un desastre cuando se trata de hacer regalos!
And, in fact, I had already made such an app: Whantit was my final project in @IronhackMAD. It was basically that: a social wish list. You can check the 5 years old repo here github.com/FrBosquet/want…
Y, de hecho, ya había hecho una aplicación así: Whantit fue mi proyecto final en @IronhackMAD. Era básicamente eso: una lista social de deseos. Puedes consultar el repositorio de hace 5 años aquí github.com/FrBosquet/wantit
But back then I was just starting in web development, I made it in Angular 4 and Express and it had a lot of unnecessary features (a database of brands and products, for example). Beyond the idea, there was little to take advantage of it
Pero por aquel entonces estaba empezando en el desarrollo web, la hice en Angular 4 y Express y tenía un montón de funcionalidades innecesarias (una base de datos de marcas y productos, por ejemplo). Más allá de la idea, poco partido se le podía sacar
Puedes leer la entrada que escribí en su momento sobre Whantit en el blog. Cuando hice esa app estaba en la locura final de Ironhack y me lie la manta a la cabeza con la API de productos, las interacciones sociales, animaciones... La app estaba chula para trastear un rato, pero no cumplía su función fundamental, que era añadir deseos y hacer regalos. Con Wanthat quería resarcirme de aquello, hacer algo más sencillo pero que permitiese al usuario gestionar este aspecto de forma dinámica y fácil. Y a mi poder desarrollar la app rápido, pudiendo añadirle funcionalidades con el tiempo en un stack en el que estuviese cómodo.
Las piedras en el camino para desarrollar una aplicación, edición Fran
So I decided to start from scratch: A modern, attractive web app that my friends could use, with a stack that I am comfortable with and that I could develop quickly (before Christmas, so I can get ThreeJs journey)
Así que decidí empezar de cero: Una aplicación web moderna y atractiva que pudieran usar mis amigos, con un stack con el que me sintiera cómodo y que pudiera desarrollar rápidamente (antes de navidades, para poder conseguir ThreeJs Journey).
Tweet not found
The embedded tweet could not be found…
El problema era este último: Soy lentísimo con mis proyectos paralelos. Y una de las razones es que tengo cierta manía a las librerías y frameworks
Desde que terminé Ironhack y conseguí mis superpoderes (el conocimiento para desarrollar webs y apps) y hasta el momento en el que escribí estos tweets no había logrado terminar ningún proyecto. Empecé mil cosas: Una reescritura con multijugador por websockets de IronGunz, un reboot en React del blog, una app para ver el orden en el que ver las pelis de Marvel, un juego de rol por turnos también multijugador, un gestor de gastos llamado Spencer... Todas murieron por el camino por el mismo motivo que no terminé el curso de Wes Bos: Perdí el interés y no me apetecía seguir trabajando en ellas.
Así que en el momento de afrontar Wanthat hice un poco de introspección buscando detectar por qué no era capaz de terminar nada. Llegué a la conclusión de que el problema era que me entretenía demasiado desarrollando tecnologías y no con el proyecto en sí: Me podía tirar una semana haciendo un select para mis formularios, o intentando desplegar funciones lambda en Amazon. Para cuando tenía que juntarlo todo y hacer algo útil, ya había perdido el interés.
Me gusta saber cómo funcionan las cosas y, en particular, cómo se hacen en #JS y #CSS. Si puedo recorrer un array con JS nativo, ¿por qué instalar Lodash?
Why put in a super heavy dependency and learn new abstractions? Why another documentation to consult? Why not do it natively? #useThePlatform
¿Por qué poner una dependencia superpesada y aprender nuevas abstracciones? ¿Por qué consultar otra documentación? ¿Por qué no hacerlo de forma nativa? #useThePlatform
So over the years I've developed a lot of dislike for things like Bootstrap, jQuery, Tailwind, Ramda, Material UI... all those fancy things that people install because they're too lazy to learn JS or CSS properly
Así que a lo largo de los años he desarrollado una gran aversión por cosas como Bootstrap, jQuery, Tailwind, Ramda, Material UI... todas esas cosas extravagantes que la gente instala porque son demasiado perezosos para aprender JS o CSS correctamente.
Lo cual es muy hipócrita por mi parte, ya que podríamos meter en ese saco abstracciones aún mayores como #react, #express o #apollo, de las que soy un devoto usuario
Esta manía venía de cuando empece en Ironhack y la gente saltaba a usar librerías y frameworks sin saber cómo funcionaban las cosas por debajo. A mi esto me daba mucha rabia porque los veía estampándose con cosas como Bootstrap porque no tenían ni idea de como funcionaba CSS por debajo.
Por otro lado, en Ironhack y en FreeCodeCamp intenté familiarizarme con jquery, lodash y bootstrap, pero nunca llegaron a hacerme click y no me gustaba usarlos. Me parecían abstracciones mas complejas que usar JS o CSS directamente. Les cogí mucha manía y esto luego me penalizó porque me cargué de muchos prejuicios para con otras librerías. Por ejemplo Tailwind, que tardé muchísimo en probarlo y me arrepiento de no haberlo hecho antes.
También había leído por ahí sobre los inconvenientes de atiborrar de librerías tus proyectos: Cómo hacían mas lenta la carga de la aplicación al tener que mandar mas JS o CSS al cliente. Tenía muy interiorizado que todo lo que pudieras hacer tú, debías hacerlo. Sumado a ello, me entretiene bastante resolver problemas sencillos de código así que si puedo hacer un flatmap yo mismo, ¿para qué voy a instalar Lodash?
Visto en retrospectiva esta vision dogmática de las dependencias me impidió completar proyectos que me hubiesen hecho mucha ilusión, como el mencionado Irongunz Online o Spencer.
I've never been a big fan of BaaS either, so whenever I'm planning a project I end up deploying a server on heroku. Or a VM running on digital ocean, with nginx breaking with every change 😱
Tampoco he sido nunca muy fan de BaaS, así que siempre que planeo un proyecto acabo desplegando un servidor en Heroku. O una VM corriendo en digital ocean, con Nginx rompiéndose con cada cambio 😱.
This means that every time I start a project I end up investing MANY months and I never complete it. The last one is Spencer, an app to manage my expenses. Been working on it for more than a 1.5 years and I'm not even close to be done
Esto significa que cada vez que empiezo un proyecto acabo invirtiendo MUCHOS meses y nunca lo termino. El último es Spencer, una aplicación para gestionar mis gastos. Llevo trabajando en ella más de un año y medio y ni siquiera estoy cerca de terminarla.
Por BaaS aquí me refiero a Backend as a Service, qué es básicamente delegar el backend de tu aplicación a un servicio externo en lugar de desplegar tu infraestructura. Por ejemplo, hay muchos servicios que te permiten definir funciones lambda como firebase, o desplegar una base de datos Postgres como Supabase. Esa idea a mi me parecía impura por el hecho de desperdigar los servicios y perder tiempo en peticiones de red entre unos y otros. Lo que nunca reflexione, hasta ese momento, es sobre el hecho de que ese tiempo no era un problema. Pero tener que desarrollar y mantener yo mismo todas las capas de un servidor si que lo era.
De nuevo, esta manía probablemente venía de IronHack donde la base de datos que usamos (Un BaaS de MongoDB) nunca me llego a gustar y generé cierto prejuicio ante todo lo que no fuera montar una app completa en un servidor desde 0.
Construyendo una app en tiempo record (Personal, pero record)
Aware of this limitation, I decided to change my mindset a bit. I only had 2 months to make it. Normally I start setting up webpack from scratch for my React apps. Instead of wasting half a day on that, I started with CRA with the TS template LIKE NORMAL PEOPLE DOES
Consciente de esta limitación, decidí cambiar un poco mi mentalidad. Sólo tenía 2 meses para hacerlo. Normalmente empiezo a configurar webpack desde cero para mis aplicaciones React. En lugar de perder medio día en eso, empecé con CRA con la plantilla TS COMO HACE LA GENTE NORMAL
Aquí viene un poco el giro y la moraleja de la historia: Hay mucho software libre sobre el que empezar a materializar tus ideas. Para el que no tenga conocimientos técnicos: Yo era el arquitecto que cocía sus propios ladrillos y con este proyecto decidí comprar placar de pladur en Leroy Merlin.
Por CRA aquí me refiero a Create React App, que era la herramienta que creó Facebook con la que podías automatizar la creación de SPAs (single page applications, o aplicación mono página) en React.
Desde que escribí este post, CRA ha sido deprecado por el equipo de React, que ya ni siquiera es parte de Meta (Facebook). Ahora las SPAs de React se crean con Vite, pero lo normal hoy en día es hacer MPAs (aplicaciones multi página) usando NextJs como la que estas leyendo ahora, y así lo recomienda la documentación de React. Pero en su momento CRA era la herramienta de facto para crear apps en React. Si estas leyendo esto y no eres técnico, entiendo que en este momento te he perdido totalmente. Otro día hare un post para aclarar todo este jaleo de servidores, capas de persistencia, React, SPAs, MPAs, SSR, SSG, etc.
For DB, instead of setting up a Postgres on a Docker and an Apollo or Express server, I said to myself: let's go with Firebase as cool kids do! 🚀
Para la base de datos, en vez de montar un Postgres en un Docker y un servidor Apollo o Express, me dije: ¡vamos con Firebase como hacen los niños guays! 🚀
Tweet not found
The embedded tweet could not be found…
En un periquete tenía resuelta la autenticación con Single Sign On. Un par de líneas más y ya estaba almacenando usuarios en Firestore. En otro minuto tenía funciones corriendo en la nube. Y en dos comandos estaba alojando la web y desplegando con un CLI_
Antes de esto había trasteado Firebase un poco en RedRadix y en Taxfix, y tenía curiosidad sobre todo por lo fácil que me había parecido crear una base de datos documental y conectar aplicaciones a ella. Pero la sorpresa vino cuando ademas ví que podía crear funciones de servidor, autenticar a mis usuarios con su cuenta de GMail, alojar la aplicación, comprar un dominio... todo en un mismo servicio. Y gratis hasta cierto punto.
El hilo entero iba sobre eso mismo: Cómo había etiquetado en base a mis prejuicios y de oídas lo que era Firebase u otros servicios o librerías, y como me había perdido una herramienta que me hubiese ahorrado muchísimo tiempo en mis proyectos paralelos. Esto terminó de abrirme los ojos y, a partir de ese momento, decidí meterme de lleno en la búsqueda de servicios y librerías que me pudieran arreglar cada una de las papeletas que me iban surgiendo en el proyecto.
Covered in backend, the application looked ugly as hell. And CSS modules are a pain to use for me. So before wasting more time in display:flex’s I started to check which component libraries we have available. And at the end I settled on @chakra_ui
Cubierto en backend, la aplicación se veía fea como el infierno. Y los módulos CSS son un dolor de usar para mí. Así que antes de perder más tiempo en display:flex's empecé a comprobar qué librerías de componentes tenemos disponibles. Y al final me decidí por @chakra_ui
Tweet not found
The embedded tweet could not be found…
Y en cuatro imports ya parecía una verdadera WebApp. Con modo oscuro y responsive casi desde el primer momento. Sin perder tarde y media en un sistema modal. Y con un muy buen aspecto visual. Gracias @thesegunadebayo por esta obra de arte
Siguiendo con lo de antes, en lugar de perder 4 semanas en diseñar un sistema de componentes feo y poco accessible, delegué esa tarea en una librería y me llevé una grata sorpresa. Descubrí Chakra en un video de Miguel Angel Duran y me convencí en un stream de Kitze: Chakra es una colección impresionante de componentes preestilados y accesibles que ademas son muy bonitos y puedes personalizar. En la práctica es directamente un sistema de diseño listo para construir lo que necesites. Tiene sus peros, pero los discutiremos más adelante.
Segun Adebayo es el creador de Chakra
¿Animaciones? @framer motion. ¿Formularios? #Formik. ¿Internacionalización? #i18next. Suelo incluso escribir mis propios selectores de fechas. ¿Aquí? #react-day-picker. ¿Búsqueda en firestore? @Algolia. ¿Scrapping? #cheerio-js y #axios
Muchas librerías: Framer motion es una librería para hacer animaciones creada por la gente de Framer. A día de hoy diría que es el standard en animaciones en React. Formik igual pero para formularios. React Day Picker es un componente de selector de fechas, ya que Chakra no incluye (o nó incluía) uno.
Algolia es básicamente una ñapa que tienes que poner sobre Firestore: Este último NO permite hacer búsquedas indexadas, por lo que si quieres hacer una búsqueda parcial por nombre o email por ejemplo, tienes que descargar todos los documentos y filtrarlos tú manualmente. Esto me parece suficiente como para no usar Firestore en un proyecto serio, pero lo descubrí cuando estaba ya a medio camino. Algolia es una solución intermedia que crea una base de datos relacional (SQL) para crear indices de tus documentos.
Básicamente: Cada vez que creas un documento en Firestore, se despacha un webhook que avisa a Algolia. Este crea un registro en una base de datos SQL con el mismo id que tiene tu documento en Firestore y los campos que quieras indexar (nombre, email, dirección... lo que configures). Cuando tienes que hacer una búsqueda parcial (En nuestro ejemplo, buscar amigos por email o nombre), en vez de buscar en Firestore, buscas en Algolia. Este te devuelve los ids de los documentos que coinciden con tu búsqueda y luego tu vas a Firestore a buscarlos. Es un apaño, pero funciona bien e integrarlo es bastante sencillo.
Axios está deprecado en favor de fetch, que es la solución nativa del navegador para hacer requests. Cheerio está bastante divertido, lo sigo usando a día de hoy en Taxfix: Es una librería que te permite hacer scrapping de paginas web con una API similar a la de jQuery. Es decir, puedes seleccionar elementos del DOM y extraer su contenido.
Si bien quizás todas estas no fuesen las mejores opciones, me tomé el tiempo de probarlas y me solucionaron la necesidad que tenía en ese momento. Redundando sobre el tema del hilo: No hace falta reinventar la rueda, hay mucho software libre que te puede ayudar a desarrollar tu idea y no hay que tener reservas a la hora de probarlo.
0 wheels reinvented. Spending two or three afternoons a week, I put the skeleton together in a month. And by the beginning of December I had a working version of the app. Cristina and I created our users and first wishes and I kept working on the app.
0 ruedas reinventadas. Dedicando dos o tres tardes a la semana, monté el esqueleto en un mes. Y a principios de diciembre ya tenía una versión funcional de la aplicación. Cristina y yo creamos nuestros usuarios y primeros deseos y yo seguí trabajando en la aplicación.
The app does real-time scraping of wish links. So if you try to add something from amazon, it tries to pull the information from amazon: title, price, photo, description.
La aplicación scrapea en tiempo real los enlaces deseados. Así, si intentas añadir algo de amazon, intenta extraer la información de amazon: título, precio, foto, descripción.
El scrapper fue lo más complicado de hacer y hay muchas dominios con los que no funciona o lo hace de manera inconsistente. Pero cuando funciona es muy satisfactorio ya que te rellena automáticamente el formulario con la información del producto que quieres. Para esto me apoyé en el protocolo OpenGraph. Como en muchas páginas esto no funciona, cree scrapers específicos para marketplaces mas o menos relevantes como Zalando o Asos. Utilicé para ello cheerio creando scrappers adhoc que se disparaban según el dominio de la URL.
If you are looking for your friends, @algolia takes care of real-time searching of a replicated firestore database with indexed email, display name and @
Si buscas a tus amigos, @algolia se encarga de buscar en tiempo real en una base de datos firestore replicada con el correo electrónico indexado, el nombre para mostrar y @.
If a friend receives a gift or buys something you were going to give them, firebase informs you using push notifications
Si un amigo recibe un regalo o compra algo que le ibas a regalar, firebase te informa mediante notificaciones push
Firestore te dá la oportunidad de mantener actualizada la UI en tiempo real de forma muy sencilla, sin tener que pelearte directamente con websockets (lo cual suele ser problemático). Básicamente, en lugar de pedir la información de un recurso, lo que haces es suscribirte a ese recurso. Si el recurso cambia en tu servidor, también lo hace en tu navegador y React se encarga de actualizar la UI. Si estas viendo el perfil de una amigo, y en ese momento tú amigo añade un deseo, veras el deseo aparecer delante de tus narices, sin recargar.
Esto es un añadido muy chulo pero realmente no aporta demasiado a Wanthat, ya que rara vez vais a coincidir usando la app. Si en tu caso estas haciendo un chat o una app colaborativa, es una característica muy interesante que ofrece Firestore que deberías tener en cuenta.
If the scrapper can't find a picture, you can upload one yourself. Hosted on firebase, of course (I know what vendor lock is, don't come and tell me how stupid I am for putting all the eggs in the same basket. I already know)
Si el scrapper no encuentra una foto, puedes subir una tú mismo. Alojada en firebase, por supuesto (ya sé lo que es vendor lock, no vengas a decirme lo estúpido que soy por poner todos los huevos en la misma cesta. Ya lo sé)
Uno de los cons más grandes que encontré al usar el ecosistema de Firebase es cómo te ata a sus APIs (lo que se conoce como vendor lock), y con este post quise dejar claro que... bueno, que lo sabía y que me daba igual.
Tiempo después quise migrar la base de datos de Wanthat a una relacional y terminé desistiendo precisamente por esto, porque implicaba reescribir toda la capa de persistencia de datos. Por lo que quizás hoy si que me pesaría mas el vendor lock a la hora de decidir que tecnologías usar.
No me arrepiento de haberlo hecho así, ya que me permitió desarrollar la app muy rápido y sin tener que preocuparme de nada mas que de la lógica de negocio. Pero hay una lección aprendida en ello.
So I found the answer to "Why not do it natively?": BECAUSE IT TAKES 10 TIMES LONGER YOU DUMBASS. It took me a long time to understand it, I'm not as smart as you guys. And I dont use libraries to figure it out 🤣
Así que encontré la respuesta a "¿Por qué no hacerlo de forma nativa?": PORQUE LLEVA 10 VECES MÁS TIEMPO, IDIOTA. Me tomó mucho tiempo entenderlo, no soy tan inteligente como vosotros. Y tampoco uso librerías que me ayuden a entenderlo 🤣.
Esta es en síntesis la moraleja del hilo, en caso de que alguien se sintiera (o sienta) tan frustrado como yo por no ser capaz de terminar ningún proyecto: Es muy fácil crear funcionalidad si lo haces encima del enorme ecosistema que ya existe en la web. Si como yó disfrutas entendiendo cómo funcionan las cosas por debajo y como puedes implementar funcionalidades, también es muy fácil perderse en una mismo e invertir valioso tiempo en construir versiones deficientes de soluciones que ya existen y puedes usar gratis. Por eso creo que es importante constantemente evaluar qué quieres hacer y cuales son tus opciones. En mi caso quería construir un producto, no librerías ni frameworks, y tomé el camino de la menor resistencia.
Conozco a muchos desarrolladores que considerarían esto una perogrullada, o que no tienen ninguna intención de construir nada fuera de su trabajo. Pero si alguno que sea tan cabezón como yo lee esto y le sirve para cambiar su mentalidad, me doy por muy satisfecho.
Final feliz
Christmas Eve arrived and the computer-assisted miracle of Christmas happened: Cristina gave me #threejsJourney! 🎉
Llegó Nochebuena y se produjo el milagro de la Navidad asistido por ordenador: Cristina me regaló #threejsJourney 🎉
I was thrilled for having the coolest course in the universe. I have already completed the first module and I assure you that it is worth every penny
Me emocioné por tener el curso más genial del universo. Ya he terminado el primer módulo y os aseguro que vale cada céntimo
But also thrilled for having been able to create something with my hands, and for that something fulfilling its purpose. Normally I create a lot of things but none of them end up working fully. And that's frustrating
Pero también emocionado por haber sido capaz de crear algo con mis manos, y que ese algo cumpla su propósito. Normalmente creo muchas cosas pero ninguna acaba funcionando del todo. Y eso es frustrante.
After that, Cristina also got a couple of gifts from me that she had added to the platform. And she loved them! A couple of friends signed up and are also using it. And I kept cleaning up my backlog and adding missing features
Después, Cristina también recibió un par de regalos míos que había añadido a la plataforma. ¡Y le encantaron! Un par de amigos se apuntaron y también la están utilizando. Y yo seguí limpiando el backlog y añadiendo características que faltaban
I created the manifest to install the app as a PWA on mobiles
He creado el manifiesto para instalar la aplicación como una PWA en móviles.
I created a chrome extension that allows you to go to the create wish screen directly using the current tab URL chrome.google.com/webstore/detai…
He creado una extensión para Chrome que te permite ir directamente a la pantalla de creación de deseos utilizando la URL de la pestaña actual chrome.google.com/webstore/detai...
I bought the wanthat.io domain
He comprado el dominio wanthat.io
Esta parte del proyecto me gustó mucho ya que aprendí a hacer esas tres features tan resultonas (PWA, extension y dominio) muy rápido y fácil, con la inercia y la confianza que llevaba del proyecto. A esa parte final en la que va saliendo todo rápido yo la llamo el sweetspot y es lo que más me gusta de desarrollar software.
La extensión está aquí. A día de hoy se ha roto la UI por alguna actualización de chrome, pero sigue funcionando.
And that was my last ticket before the 1.0.0 milestone. Mission accomplished. Wish granted. Achievement unlocked: my first product published on the internet 🎉
Y esa fue mi última tarea antes del hito 1.0.0. Misión cumplida. Deseo concedido. Logro desbloqueado: mi primer producto publicado en internet 🎉.
Después de Wanthat he sacado adelante otro proyecto de cierto calado, la web de cristinadevaux.com, y algunos otros side projects menores: Una invitación virtual para mi boda, una herramienta de gestión interna para la empresa de mi primo, una web para el campeonato de karts que tengo con los colegas, este blog...
Lanzar una 1.0 en un proyecto en solitario es una sensación rarísima, ya que internamente se siente como un triunfo enorme (aunque tenga 0 repercusión) pero externamente es un tio con gafas, encorvado sobre el teclado, haciendo un push a master 🤣.
I've really enjoyed developing with this philosophy of not reinventing the wheel. I have learned a lot about development by working with libraries that are almost standard. And now I have a lot more tools to materialize my ideas and to do it FAST
He disfrutado mucho desarrollando con esta filosofía de no reinventar la rueda. He aprendido mucho sobre desarrollo trabajando con librerías que son casi estándar. Y ahora tengo muchas más herramientas para materializar mis ideas y hacerlo RÁPIDO
So if you take my advice: Don't be stubborn. Keep a curious attitude and don't prejudge without trying things out. You're probably missing out on a lot of good stuff. It's as good advise for life as it is for installing NPM packages
Así que si sigues mi consejo: No seas cabezón. Mantén una actitud curiosa y no prejuzgues sin probar las cosas. Probablemente te estés perdiendo muchas cosas buenas. Es tan buen consejo para la vida como a la hora de instalar paquetes NPM
And if you want to try wanthat.io, it's obviously free. You just need a Gmail account (I will add more login and signup methods). Your feedback will be very valuable for me to keep improving it, so don’t bother to DM me if you find a bug 🙏
Y si quieres probar wanthat.io, obviamente es gratis. Sólo necesitas una cuenta de Gmail (añadiré más métodos de inicio de sesión y registro). Tus comentarios son muy valiosos para que pueda seguir mejorándolo, así que no tengas reparo en enviarme un DM si encuentras un error. 🙏.
Nunca añadí métodos de login adicionales. De hecho aparqué el proyecto después de sacarlo, ya que empecé la mencionada web de Cristina de Vaux, y la unica mejora que hice en Wanthat fue mejorar los scrapers cuando dejaron de funcionar en Amazon. En un momento dado quise rehacer la capa de persistencia de datos como mencioné antes y eliminar la necesidad de Algolia. Pero resulto ser una tarea titánica y lo dejé de lado. Hace un año también se me ocurrió intentar rehacer la aplicación en t3.gg ya que por aquel entonces consumía mucho contenido de Theo Brownee y tenía curiosidad. Pero igualmente la tarea se me iba de las manos y lo dejé a los pocos días.
Así qeu hasta allí llegó Wanthat.
Thanks for reading this far! I'm off to continue with #threejsJourney
¡Gracias por leer hasta aquí! Me voy a continuar con #threejsJourney
Conclusiones
En este hilo se mezclaron muchas cosas y algunas ya las hemos comentado. El principal punto, como ya he hecho incapié reiteradamente, es cómo apoyándome en librerías open source logré acelerar mi proceso de desarrollo hasta el punto de vencer al aburrimiento y terminar un proyecto antes de que este atacara. Si estas en punto parecido, te animo a que cambies tus hábitos en tus proyectos personales y antes de implementar una feature pegues una búsqueda en Google a ver si alguien ya lo ha hecho. Desde Wanthat yo he seguido aplicando esta metodología y he terminado muchos proyectos que de otra manera hubiesen quedado en el limbo. Y en el proceso he descubierto muchas librerías que no solo me resuelven la papeleta, sino que me hacen más divertido programar.
Por otro lado, me gustaría hacer un pequeño análisis de las principales tecnologías que usé en su momento y como ha evolucionado mi visión de las mismas desde entonces.
Firebase
Firebase me pareció la leche en este proyecto, las bases de datos son bastante peculiares y la facilidad de uso es increíble. Básicamente son JSONs a los que te suscribes en tiempo real. Cuando yo empecé a programar en Flash hace 20 años esto era exactamente con lo que soñaba: Hay datos, llamas a una función y se guardan en un servidor. Abres tu aplicación y están ahí como los dejaste.
Pero tiene un gran pero: Firebase te ata a sus APIs. Si quieres migrar a otro proveedor de servicios, o a una base de datos relacional, o a un sistema de autenticación diferente, o a un sistema de notificaciones diferente... vas a tener que reescribir toda esa capa de tu programa, o el programa entero. Si quieres llevarte tus archivos de imagen a otra parte, buena suerte descargando y alojando en otro lado. Si quieres hacer un despliegue, todo va a traves de su CLI. Todo está firebasificado y diseñado para que construyas no con Firebase, sino sobre Firebase.
Para más INRI la documentación, como la de cualquier producto de Google, es un HORROR lovecraftiano. Te recomiendo mantenerte alejado de semejante pozo de información confusa, desactualizada, inconexa y febril.
Por otro lado, es bien sabido que si tu app coge tracción, es muy fácil que las lecturas de base de datos se multipliquen exponencialmente y con ello la factura de tu proyecto, dadas las limitaciones de la base de datos documental y que Firestore te cobra por lectura/escritura a partir de cierta cantidad de operaciones. Así que si te llama la atención este servicio y estas pensando en construir una app, te recomiendo primero montar algo pequeñito para conocer Firebase. Ya que te permite manejar el stack entero desde el despliegue, hasta funciones lambda, alojamiento de archivos y por supuesto frontend, puedes montar una web sencilla en un fin de semana. Una app de TODO's o algo así puede ser un buen proyecto de reconocimiento.
Una vez que tengas ese conocimiento evalúa si quieres invertir tiempo en montar algo más serio con Firebase, con sus pros y sus contras. En mi caso, tras Firebase he probado con Supabase, Railway y Vercel, y me quedo con Vercel de lejos. Todas ellas tienen cosas mejores y peores, pero la facilidad que te da esta última para integrar todo el stack es incomparable.
En caso de que estés pensando que estos servicios parecen un poco amateur o poco sofisticados: Si eres un solo developer como yo ni me plantearía aprender GCP o AWS. Son demasiado complejos y no vas a sacarle partido. Y para tu web con 2 usuarios concurrentes te aseguro que no necesitas una app dockerizada con Kubernetes balanceando carga. Si quieres aprender algo, aprende Vercel o Netlify, que son los que te van a permitir desplegar tus proyectos personales de forma gratuita y sin complicaciones.
Si te quieres dedicar profesionalmente a devops, Google Cloud, Azure o AWS son un must. Pero para proyectitos amateur como hago yo hazme caso y mejor elige el camino de menor resistencia.
Chakra UI
Para mi Chakra fue una revelación: Me permitió tener una UI que parecía moderna y profesional sin saber diseñar y sin invertir ni un minuto en Framer o Figma. Esto fue para mi como la segunda venida de Jesucristo: Mis proyectos hasta este punto se morían intentando hacer UIs resultonas, por ejemplo Spencer:
Ui de Spencer en framer. Me tire semanas trabajando en esto, cuando fuí a implementar el código estaba ya harto del proyecto
El problema de Chakra, y por lo que deje de usarlo es:
-
Es una solución basada en CSS en JS. Específicamente, Emotion. Esto da problemas normalmente en SSR ya que las circunstancias en el servidor no siempre son las mismas que en el cliente. Terminé de desechar este tipo de soluciones trabajando con Next y Framer, no había manera de que renderizar lo mismo en cliente y servidor. Ademas, es peor en rendimiento que CSS puro ya que bloquea el hilo de ejecución de JS. De hecho en Wanthat hay algunas animaciones que se atascan en el móvil por culpa de esto mismo.
-
La API. Si bien esta basada un poco en la misma idea que otras librerías como Native Base y usa convenciones comunes, no es muy intuitiva, es verbosa y está totalmente ligada a componentes React. Si bien no es difícil de aprender, y es bastante componible, con el tiempo (y al descubrir las bondades de Tailwind) le he cogido bastante manía.
La solución que uso a día de hoy es Radix UI + Tailwind con los componentes de Shadcn. Radix UI es una librería de componentes accesibles y performantes que vienen sin estilos, por lo que puedes usar las clases de Tailwind para estilarlos. Shadcn es un desarrollador de Vercel que ha creado una librería de componentes para Radix UI, que son muy bonitos, ligeros, accesibles. La combinación de ambas es muy potente y te permite crear tu sistema de diseño de manera fácil y rápida.
No hace mucho ha salido Radix UI Themes que incluye la capa visual sobre la de accesibilidad, basado también Tailwind, por lo que Radix UI se ha convertido en un sistema de diseño completo. Vendría a sustituir en este caso a ShadcnUI. Aun no lo he probado pero tiene muy buena pinta.
Otras librerías en este sentido son Daisy UI o Next UI, que tienen muy buena pinta y a las que te invito que les pegues un ojo si estas buscando una solución para darle estilos a tu próximo proyecto.
Animaciones: Framer motion también fue una librería que me encantó en su momento, pero que he dejado de usar por el mismo motivo que Chakra: Es una solución basada en CSS en JS y no es tan performante como CSS puro. La API también me dejo bastante desencantado, teniendo que mezclar mucha lógica de animaciones entre la estructura de tu página, los estilos y tú lógica de negocio.
Aun asi, si quieres hacer animaciones complejas, es una librería muy potente y fácil de usar mientras tu jerarquía de componentes se mantenga limpia y ordenada. A mi siempre se me va de las manos y acabo odiando todo lo que tiene que ver con animaciones. Hoy en día intento hacer todo lo que pueda en CSS y como mucho con intersection observers y la api experimental de animation-timeline de CSS. Si necesito algo mas complejo, es que estoy sobrecomplicando la página y necesito revaluar qué quiero hacer y si merece la pena.
Formik
NO necesitas una librería de formularios en React. Necesitas aprender la api de formularios de HTML5 y usarla. Si se te quede pequeña, usa JS. Y cuando el JS se vaya de madre, entonces y solo entonce usa una librería React. Eso lo aprendí algunos proyectos después y es genial la cantidad de código que te ahorras cuando pasas de integrar estos monstruos en tus micro proyectos.
Si llego al punto de necesitar una librería de formularios, pues supongo que estará entre React Form y la propia Formik. Se que suena a que he vuelto a caer en el dogmatismo anti librerías 🤣 pero la diferencia en este caso es que hablo con conocimiento de causa y tras muchos formularios escritos.
Y qué pasa con threejsJourney?
Qué bonico es el logo copón
Pues el curso es genial, pero tal y como comentaba en uno de los primeros Tweets:
Don't get me wrong: I have no problem with the price. It seems cheap to me in fact. The problem is ME with the courses: I buy them, I don't finish them
No he terminado el curso. Lo retomo de vez en cuando, hago unas cuantas lecciones y lo aparco unos meses. Es muy entretenido y construyes cosas muy chulas. Bruno Simon es un profe genial, aunque habla MUY lento puedes acelerar el video. Si no sabes Ingles ni lo intentes, pero si tienes un nivel bajo el chico es Frances y tiene un acento bastante asequible de seguir. A parte de los subtítulos. En X.com siempre está al quite para echar una mano, usando el hastag #threejsJourney, o mencionándolo, como poco te deja un like. Y creo que hasta hay un discord, pero nunca he entrado. Para mi el problema, si es que hay alguno, es que son lecciones de 1-2 horas la mayoría y rara vez tengo energía para mantenerme atento tanto rato.
En el computo general creo que merece totalmente la pena y, si tienes la oportunidad de hacerte con el, no lo dudes. Es un curso muy completo y te permite hacer cosas qué, si aun no te has metido en el mundo de Web GL, ni te imaginas. Si te gusta el 3D y tienes una base de javascript, es un must. Desde que me lo regaló mi mujer hace casi dos años lo ha ido actualizando y ahora tienes por ejemplo la parte de ReactThreeFiver o la actualización de todos los ejercicios a Vite, que no estaban cuando lo compré. Es decir, que el curso sigue evolucionando y mejorando constantemente. Muy recomendado.
Y qué pasa con Wanthat?
Pues ahí está! Nadie siguió la broma en Twitter y la verdad es que por usuarios tiene a mis amigos y ya. Pero mi mujer y yo lo usamos constantemente y lo utilizamos para regalarnos en cumpleaños y aniversarios. Como he comentado, tengo en mente reescribirla con el stack que uso ahora, sin prisa.
Si a raiz de este hilo te han dado ganas de probarla, por supuesto puedes hacerlo en wanthat.io. Agrégame, soy @Franbosquet.
Y hasta aquí el AAR de este mes. Espero que hayas disfrutado leyendo este tocho nostálgico. Como aun no tengo sistema de comentarios en este blog, si quieres comentar algo, puedes escribirme por X. Muchas gracias por leer hasta aquí y nos vemos en el siguiente post!