Video Summary and Transcription
Esta charla analiza los desafíos que se enfrentan al implementar o migrar una pila heredada a Next.js y Contentful en proyectos a gran escala. Se enfatiza la necesidad de un análisis cuidadoso y una estimación de tiempo y recursos. La charla también destaca los beneficios de Next.js al facilitar la colaboración con equipos aislados e integrarse con otros frameworks. Se abordan los desafíos de usar un CMS sin cabeza en proyectos a gran escala y se sugieren estrategias para manejar la falta de disponibilidad y los fallos. También se enfatiza la importancia de utilizar el estado global de manera inteligente y promover la reutilización de código, junto con técnicas para superar los desafíos en proyectos a gran escala.
1. Introducción a los desafíos en proyectos a gran escala
Hola, soy Leonidas. Hablaré sobre los desafíos que se enfrentan al implementar o migrar una pila heredada a Next.js y Contentful en proyectos a gran escala. Estos desafíos son diferentes en proyectos de pequeña y mediana escala. Cada organización tiene su propio modelo de negocio y necesidades específicas, por lo que no existe una solución única. El propósito es crear conciencia y proporcionar consideraciones para este viaje.
Hola, soy Leonidas. He trabajado como ingeniero front-end durante unos 15 años y actualmente trabajo como líder de capítulo front-end para Vodafone Grecia. Hoy les hablaré sobre los desafíos que pueden enfrentar si intentan implementar o, peor aún, migrar una pila heredada a un marco moderno de React, como Next.js, junto con un CMS sin cabeza como Contentful, pero en un proyecto a gran escala.
Next.js, como ya saben, es un excelente marco de nodo de React de pila completa y Contentful es un conocido CMS sin cabeza. Pero cuando hablamos de proyectos a gran escala, los desafíos son completamente diferentes a los que pueden enfrentar en un proyecto de pequeña o mediana escala. En la mayoría de los casos, tener que migrar uno o más proyectos a gran escala significa que ya eres parte de una gran organización, lo que plantea desafíos adicionales por sí solo.
Con el tiempo disponible, es realmente difícil discutir también soluciones para estos desafíos. Aparte del factor tiempo, cada organización sigue su propio modelo de negocio y tiene necesidades específicas, lo que hace que una solución no sea apropiada para todos los casos. Por lo tanto, el propósito de esta presentación es crear conciencia sobre los desafíos que es posible que no hayan enfrentado hasta ahora y lo que deben considerar si usted y su equipo deciden dar este gran paso y comenzar este emocionante viaje. Así que comencemos. Comencemos con el hecho que se aplica a todos los marcos modernos y no solo a los mencionados anteriormente.
2. Desafíos en Proyectos a Gran Escala
Si trabajas en un proyecto con código heredado, considera los beneficios de un marco de pila moderno. Analiza el proyecto y estima el tiempo y los recursos necesarios para la migración. Sin embargo, en proyectos a gran escala, esta estimación puede no ser factible. La nueva pila debe coexistir con la pila antigua durante el período de migración, lo que requiere soluciones temporales para el registro, el intercambio de sesiones, los recorridos entre pilas, la duplicación de código y el intercambio de componentes de UI.
Si trabajas en un proyecto que utiliza mucho código heredado, tú y tu equipo tarde o temprano comenzarán a considerar los beneficios de un marco de pila moderno. También será muy fácil convencer a los empresarios de tu empresa. Un entorno más estable, un mejor rendimiento, un tiempo de desarrollo más rápido, una integración continua y una entrega continua más eficientes y todo esto conducirá a un tiempo de comercialización más rápido, mejorará el ranking de SEO y ayudará a tus clientes.
Entonces, ¿qué vas a hacer? Tendrás que analizar el proyecto y diseñar una estimación aproximada del tiempo y los recursos necesarios para que ocurra la migración. Y estarás listo para comenzar. Suena perfecto. No exactamente. En la mayoría de los casos de proyectos a gran escala, analizar y hacer el diseño inicial para tener esta estimación aproximada ni siquiera es factible. Y si logras hacerlo, terminarás con algo como, `jefe, necesitamos de dos a tres años para migrar a nuestra nueva pila`. Las grandes organizaciones no dejarán de desarrollar nuevas características para sus clientes, por lo que no asignarán todos sus recursos para migrar a una nueva pila. Terminarás con una estimación vaga y, lo más probable, si ocurre la migración, cuando termines, las tecnologías que elegiste ya estarán desactualizadas.
Lo que debes considerar es que tu nueva pila debe coexistir durante todo el período de migración con tu pila antigua. Deberás seguir un enfoque granular y encontrar soluciones temporales para el manejo de registros en ambas pilas, si tienes un mecanismo de registro, cómo compartir sesiones entre estas dos pilas, cómo manejar los recorridos entre pilas, los recorridos que comenzarán desde tu pila antigua y terminarán en tu nueva pila, o viceversa, cómo puedes reducir la duplicación de código y el mantenimiento mientras tienes dos bases de código diferentes. Finalmente, deberás encontrar formas de compartir componentes de UI para que esto funcione.
3. Next.js y Colaboración con Equipos Aislados
Next.js es un excelente marco de pila completa que permite a los desarrolladores front-end y full-stack trabajar fácilmente con el código del back-end y del front-end en el mismo proyecto. Proporciona una experiencia de desarrollo sencilla, permitiendo la creación de funciones de extremo a extremo con facilidad. Al colaborar con equipos aislados, es importante considerar cómo organizar equipos separados que trabajen juntos en el mismo repositorio y maximizar la separación de código. Además, es posible integrar otros marcos con Next.js. Un CMS sin cabeza, como Contentful, es una opción adecuada para Next.js, ya que proporciona las funcionalidades que faltan y permite cambiar fácilmente de tecnología o CMS en el futuro.
Next.js es un excelente marco de pila completa. Como desarrolladores front-end o full-stack, nos resulta muy fácil tener siempre disponible el código del back-end y del front-end dentro del mismo proyecto. Sé dónde escribir mi código del lado del servidor, sé dónde viven mis API, dónde vive mi código del front-end. El desarrollo es mucho más rápido, me resulta fácil crear funciones de extremo a extremo y el proceso de compilación es solo un clic. Como entiendo la lógica detrás del marco y su estructura, todo es sencillo.
Supongamos que eres parte de una gran organización global, lo más probable es que tengas que colaborar con otros equipos completamente aislados porque así es como la mayoría de las grandes organizaciones asignan recursos. Tu equipo puede tener que trabajar con equipos de back-end que están en el otro lado del planeta y que quizás nunca hayan usado Next.js. Veamos este ejemplo. Tu equipo tiene una gran idea para una nueva función que será de gran valor agregado para tus clientes. El plan de trabajo de tu equipo ya está definido y tendrás que encontrar formas de encajar esta nueva función en el plan de trabajo. Tu Product Owner comunica la función y descubre que hay varios otros países que también encuentran útil esta función. Es una gran oportunidad para utilizar recursos compartidos de todos los demás países y desarrollar la función juntos para desarrollar más rápido, aumentar la propiedad y también aumentar la reutilización.
Entonces, algunas personas pueden ser asignadas de tu equipo para la parte de React de la función de IA y otro equipo que trabajará en Node.js será seleccionado. En el mejor de los casos, al equipo de back-end le resultará extraño trabajar con los mismos archivos y la misma base de código que el equipo de front-end. En el peor de los casos, este equipo puede tener opiniones fuertes y puede necesitar trabajar con un marco específico de Node.js, como por ejemplo Nest.js. ¿Está todo arruinado? No, solo necesitas considerar algunas cosas. Primero, cómo organizar dos equipos separados que trabajen juntos en el mismo repositorio con los mismos archivos. Segundo, cómo maximizar la separación de código entre esos equipos. Y finalmente, cómo puedes integrar otros marcos con Next.js.
Hablemos un poco sobre los CMS sin cabeza. En Vodafone, el CMS sin cabeza fue la elección cuando tuvimos que tomar esta gran decisión para un CMS futuro que sería nuestra fuente de contenido dinámico y datos para todas nuestras aplicaciones y dispositivos en los próximos años. Específicamente, decidimos ir con Contentful, pero hay una gran cantidad de excelentes CMS sin cabeza por ahí que más o menos lo que vamos a decir aquí se aplicará. Los CMS sin cabeza tienen grandes beneficios. Tu contenido está listo para ser servido en cualquier dispositivo. Te preocupas menos por el contenido y más por la capa de presentación, que es algo que todos los desarrolladores desean. Es agnóstico al front-end, ya sea React, Vue, Angular, como quieras llamarlo. Como resultado, tienes un CMS completamente desacoplado de tu parte de renderizado. Por lo tanto, es muy fácil cambiar de tecnología o CMS en el futuro si es necesario. Por lo tanto, un CMS sin cabeza es perfecto para Next.js, ya que Next.js proporciona todas las funcionalidades que faltan en un CMS sin cabeza. Por ejemplo, enrutamiento, SEO y en general, Next.js también admite la generación de tamaño estático, que es una tecnología en la que un CMS sin cabeza es tu mejor opción.
4. Desafíos de los CMS sin cabeza en proyectos a gran escala
Aunque los CMS sin cabeza pueden presentar desafíos en proyectos a gran escala, como la experiencia de autoría de contenido y las herramientas de SEO, es posible superarlos con una consideración cuidadosa y eligiendo el CMS adecuado. La disponibilidad de la experiencia del usuario final es crucial, incluso si tus servidores tienen una alta disponibilidad. Los proyectos a gran escala a menudo dependen de sistemas backend heredados, que pueden tener una baja disponibilidad y otros problemas. Es importante manejar la posible falta de disponibilidad y los fallos mediante el análisis de cada función, la implementación de mecanismos como banderas de características y tener un manejo avanzado de errores, registro y monitoreo. La gestión del estado global es una herramienta útil para evitar la propagación de propiedades y almacenar información con estado en aplicaciones complejas.
Aunque los CMS sin cabeza son la opción ideal cuando tienes un equipo de desarrollo interno y trabajas con frameworks modernos de JavaScript, algunos de los pequeños inconvenientes de un CMS sin cabeza pueden convertirse en desafíos cuando trabajas en un proyecto a gran escala, especialmente en una gran organización con muchos autores de contenido y requisitos más avanzados de SEO por parte de un equipo dedicado de SEO. Los resumiré en categorías: experiencia de autoría de contenido y herramientas de SEO.
Creo que puedes lidiar con ambos desafíos en un proyecto de tamaño pequeño a mediano, pero no en uno grande. Habrá casos en los que el equipo de SEO pueda necesitar funciones como mantener una lista de redirecciones de URL, editar un archivo robot.txt, previsualizar cómo Google renderiza tus páginas o metadatos. Además, en cuanto a la experiencia de los autores de contenido, aunque la mayoría de los CMS antiguos han mejorado mucho en los últimos años, cosas como la previsualización de contenido, la edición de contenido y en general la experiencia de usuario mejorada no están al mismo nivel que en algunos CMS tradicionales. Con Contentful en particular, no hay nada que no se pueda lograr gracias a sus funciones de aplicaciones personalizadas, y esto también es cierto para otros CMS sin cabeza. Puedes lograr todo, pero requiere esfuerzo por parte de tu equipo para desarrollar las funciones deseadas.
Entonces, ¿qué debes considerar? Elige tu CMS sin cabeza sabiamente en función de tus necesidades actuales y futuras. Enfócate en la capacidad de extensión, flexibilidad y soporte. La mayoría de los productos SaaS ofrecen hoy en día acuerdos de nivel de servicio (SLA) de tiempo de actividad suficientes, como 99.99999%, etc. Incluso si implementas tu propio CMS sin cabeza, es probable que lo alojes en un servicio en la nube como AWS, que también ofrece un tiempo de actividad casi del 100%. Teniendo en cuenta que también puedes utilizar una serie de capas adicionales de almacenamiento en caché para tus datos con el fin de garantizar el tiempo de actividad, incluso si tus productos SaaS fallan, entonces puedes estar seguro de que tendrás un tiempo de actividad del 100% para tus excelentes funciones. La métrica que más importa es el tiempo de actividad que experimenta el usuario final y no el tiempo de actividad que tienen tus servidores. La mayoría de las veces, las funciones en proyectos grandes y complejos dependen de una serie de sistemas backend heredados para recuperar cualquier tipo de datos. Estos sistemas, la mayoría de las veces, son manejados por diferentes departamentos en las organizaciones y pueden tener un tiempo de actividad bajo, malas prácticas de actualización de parches con largos períodos de mantenimiento y una serie de otros problemas. Además, algunas de las características de tu aplicación web pueden estar fuertemente relacionadas con funciones y servicios empresariales que pueden generar problemas no relacionados con su red. Por ejemplo, un servicio de clic para llamar donde de repente tu centro de llamadas se cae y tu función aparecerá sin respuesta para el usuario. Tal vez un chat en vivo podría ser un gran ejemplo. Y la lista puede continuar. La falta de disponibilidad en todos estos casos puede no significar una falta de disponibilidad real para tu aplicación web, pero si no se maneja correctamente, puede provocar fallos y una mala experiencia de usuario.
Entonces, ¿qué debes considerar? Debes analizar todos estos casos para cada función. Debes crear mecanismos, como por ejemplo, banderas de características, que te ayuden a cambiar la experiencia del usuario sobre la marcha cuando ocurra una crisis. Además, debes tener un manejo avanzado de errores y, finalmente, debes tener un mecanismo efectivo de registro y monitoreo para detectar casos no controlados. La mayoría de nosotros estamos acostumbrados al concepto de estado global y hemos aplicado este patrón en nuestras aplicaciones de manera extensiva. Existen varias bibliotecas populares de terceros, como Redux y MobX, que pueden ayudarte a gestionar el estado global en la aplicación. React también ofrece el API de contexto y el hook useContext con el mismo propósito. El estado global es una excelente manera de evitar la propagación de propiedades y almacenar información con estado cuando muchos de tus componentes necesitan acceder a ella. Estoy bastante seguro de que esta no es la primera vez que escuchas a alguien hablar sobre el uso excesivo o abuso del estado global o algo así. Como mencionamos antes, el estado global es una herramienta muy útil.
5. Desafíos del Estado Global en Proyectos a Gran Escala
Un proyecto a gran escala puede convertirse fácilmente en una carga con un estado global difícil de mantener. El uso excesivo del estado global puede generar código repetitivo excesivo, problemas de rendimiento y confusión para desarrolladores inexpertos. Es importante utilizar el estado global de manera inteligente y considerar el uso de bibliotecas de gestión de estado como React Query, SWR, Recoil, Jetty y Zoostack para obtener un mejor rendimiento y facilidad de uso.
Desafortunadamente, un proyecto a gran escala es el mejor terreno de juego para terminar con un estado global enorme y difícil de mantener si diseñas tu aplicación para que dependa en gran medida del estado global. El uso extensivo del estado global aumenta el código repetitivo y puede resultar muy difícil para un desarrollador inexperto o nuevo comprender lo que está sucediendo. Además, varios problemas de rendimiento pueden estar relacionados con el uso extensivo o incorrecto del estado global. Nos sorprendimos cuando descubrimos cuántas veces tendemos a utilizar el estado global sin siquiera necesitarlo. El estado global no es malo, pero su uso excesivo puede convertirlo en algo malo.
Entonces, ¿qué debes considerar? Utiliza el estado global de manera inteligente. Prueba una combinación de una biblioteca de gestión de estado global con una biblioteca de obtención de datos como React Query o SWR. Estas bibliotecas ofrecen duplicación de solicitudes, almacenamiento en caché en el lado del cliente y actualizaciones de datos sin necesidad de modificar el estado global. Por último, quiero mencionar que existen varias bibliotecas modernas de gestión de estado que se centran más en el rendimiento y la facilidad de uso, como Recoil, Jetty y Zoostack, que son excelentes alternativas a considerar.
6. Reutilización de código y superación de desafíos
La reutilización de código es crucial en proyectos a gran escala. React promueve componentes reutilizables, pero existen desafíos en la comunicación efectiva y la guía de reutilización de código y componentes. La reutilización de componentes de IU afecta la reutilización de tipos de contenido en un CMS sin cabeza. Considera patrones de herencia y composición, convenciones de nomenclatura, herramientas de documentación, flujos de trabajo y estructura de la biblioteca de componentes. Simplifica el proceso de contribución de componentes reutilizables y explora formas de reutilizar consultas GraphQL. Next.js y los CMS sin cabeza son excelentes opciones, pero los desarrolladores deben ampliar los límites y priorizar la accesibilidad y flexibilidad. Técnicas como separar el código frontend y backend, enfoque de microfrontend, banderas de características, herramientas de documentación, API de contexto y SWR, aplicaciones personalizadas, contenido como código y el patrón de Diseño Atómico pueden ayudar a superar los desafíos.
La reutilización de código es una de las cosas más importantes cuando se trata de proyectos, especialmente los de gran escala. React, por sí mismo, se basa en la filosofía de componentes reutilizables. Hay varias cosas que puedes hacer reutilizables dentro de tu proyecto, como funciones, componentes, hooks, consultas GraphQL, APIs, y la lista puede continuar.
En un CMS sin cabeza, debes centrarte en tipos de contenido reutilizables para garantizar la reutilización. Con todas estas opciones, parece fácil tener un proyecto escalable y fácil de mantener. El desafío aquí no es específico del framework o del CMS, sino específico de la escala del proyecto. Imagina un entorno en el que 15 equipos locales diferentes, además de un número ilimitado de equipos en todo el mundo, están trabajando en el mismo proyecto. Es un desafío comunicar de manera efectiva los detalles y requisitos para la reutilización de código y componentes, y es difícil proporcionar una orientación adecuada y comentarios sobre su uso del código. Es muy difícil lograr que todos estén alineados con el proceso. Y el problema con la reutilización de componentes de IU pronto llevará a problemas con la reutilización de tipos de contenido en tu CMS, ya que tus tipos de contenido deben estar mapeados con tu IU, al menos con tus componentes de IU principales.
También descubrirás que la cantidad de consultas GraphQL que utilizas para recuperar tus datos comienza a ser enorme y te encontrarás usando las mismas consultas una y otra vez. La introducción de fragmentos GraphQL es una excelente manera de mejorar esto, pero pueden llevar a malas prácticas, como el uso de fragmentos anidados si terminas abusando de este patrón. Por lo tanto, hay varias cosas que debes considerar para superar estos desafíos. Primero, intenta utilizar patrones de herencia y composición para tus tipos de contenido para lograr la máxima usabilidad. Encuentra convenciones de nomenclatura para tus tipos de contenido que no sean específicas de una función, para que puedas reutilizarlos en otros tipos de contenido de manera significativa para tus autores de contenido. Utiliza herramientas de documentación adecuadas para tus componentes de IU, como un storybook o una guía de estilo, para tener una representación clara de todos tus componentes y todas sus variaciones. Y también encuentra los flujos de trabajo adecuados y las formas de comunicarlos a tus diseñadores y equipo de negocios. Utiliza una estructura significativa para tu biblioteca de componentes. Simplifica el proceso de contribución de componentes reutilizables a escala global, centrándote en la rapidez con la que un nuevo desarrollador puede comprender el proceso. Por último, investiga formas de reutilizar consultas GraphQL, evitando problemas.
Creo que después de seis vueltas, tengo que llegar a una conclusión. No me malinterpretes, Next.js, al igual que otros frameworks populares, es genial de usar en cualquier circunstancia, y los CMS sin cabeza son el camino a seguir, y probablemente lo que usaremos en el futuro. Es por eso que elegimos usarlos y seguiremos haciéndolo. Trabajar en proyectos a gran escala requiere que los desarrolladores den un paso adicional y amplíen los límites del framework. Lo que debes buscar en un framework o un CMS es la accesibilidad y flexibilidad para poder superar todos los obstáculos. Después de plantear los desafíos, permíteme presentarte detalladamente una lista de técnicas que ya estamos utilizando o que estamos en proceso de implementar y que pueden resultarte interesantes. Hemos separado nuestro código frontend de nuestro código backend a nivel del sistema de archivos. También hemos optado por un enfoque de microfrontend para el aislamiento del equipo y un mantenimiento de código más fácil, convirtiendo un proyecto grande en varios pequeños. Utilizamos banderas de características para manejar la experiencia del usuario sobre la marcha cuando necesitamos abordar una disponibilidad. Utilizamos storybook y otras herramientas de documentación para documentar nuestros componentes. Estamos utilizando una combinación de la API de contexto y SWR para la gestión de estado global. Creamos una serie de aplicaciones personalizadas dentro de Contentful para personalizar la experiencia del usuario e integrar Contentful con otros servicios de terceros y crear funciones que son difíciles de encontrar en los CMS sin cabeza de serie. Utilizamos el enfoque de contenido como código para todo nuestro contenido, y finalmente utilizamos el patrón de Diseño Atómico para estructurar nuestros componentes. Como te dije en la introducción, no hay remedio para todos los problemas o dificultades. Quiero agradecerte por tu tiempo y espero que encuentres todos estos desafíos tan emocionantes como nosotros.
Comments