WebComponents para transformar una empresa

WebComponents para transformar una empresa

Álvaro Junqueira. Prepárate para llorar antes de celebrar, porque en este artículo te explicaré cómo una gran empresa que tenía problemas con las bibliotecas prioritarias, el versionado, la comunicación entre los equipos de Front-end y un alto acoplamiento con Angular se transformó con la creación de WebComponents.

Las grandes empresas con muchos equipos de Front-end que se ocupan de diferentes proyectos terminan enfrentando un problema común: mantener las aplicaciones con una alta consistencia en UI y UX (es difícil mantener incluso el mismo color del botón Guardar).

El desafío de mantener la consistencia es grande y muchas empresas adoptan diferentes estrategias:

  • Crear un framework o biblioteca.
  • Contratar un equipo de diseño.
  • Escribir una documentación gigante.
  • Inculcar la validación visual para testers.
  • Personalizar una biblioteca (como un bootstrap) para sus propósitos.

y por ahí va…

Todas estas iniciativas gastan tiempo, dinero y aún así no garantizan que los equipos hayan desarrollado una aplicación que sea al menos similar entre sí.



Pero primero,  ¿qué son los WebComponents y cuál es la ventaja?

Después de todo, un WebComponent es una etiqueta HTML que tú mismo creas y dentro de esa etiqueta tiene un DOM completo para desarrollar tu componente.

Text

Description automatically generated
Todo el HTML y CSS dentro de este #shadow-root es inaccesible para la aplicación, evitando cualquier tipo de conflicto (en este ejemplo, el componente se llama <twitterwidget>).

Entonces, si hoy ya conoces las etiquetas HTML estándar (como <h1> para crear un título o un <footer> para crear un footer), también puedes crear tu propia etiqueta (llamada <datepicker> o <best-name-ever> por ejemplo), y al incluir esta etiqueta en su proyecto, una estructura completa de CSS y HTML encapsulada en el interior se representará de forma nativa en el navegador.

Para esto, WebComponents usa una característica del navegador llamada ShadowDOM, que encapsula todo el HTML utilizado y lo más importante: evita conflictos CSS (es decir, si define una clase CSS en tu proyecto llamada .my-class no estará disponible dentro de tu WebComponent y viceversa). Esto hace que sea seguro crear un componente con un CSS que nunca se puede sobreescribir, manteniendo así la coherencia visual para todos los usuarios de ese componente (ninguna aplicación podrá instalar su componente e intentar realizar cambios, a menos que lo permitas a través de parametrizaciones).

La idea de este artículo no es profundizar en todos los detalles técnicos de lo que es un WebComponent, pero es muy importante que sepas que cuando quieres crear un componente visual para una empresa, probablemente no quieras que los equipos del proyecto cambien todo lo definido por el equipo de Diseño. Esta es una gran ventaja de WebComponents.

Desafíos identificados

Cuando inicié el proyecto de insertar WebComponents en la mencionada empresa, lo primero que hice fue plantear los retos a los que me enfrentaría. Ellos fueron:

Organización

¿Cómo se almacenaría el código? ¿Cómo informarán los equipos sobre los problemas? ¿Cómo pueden los equipos sugerir y solicitar nuevas funciones? ¿Cómo evitar que un proyecto que solo necesita 5 componentes tenga que instalar una biblioteca gigante de cosas que no usará?

Tecnologías e Interoperabilidad

¿Cuáles tecnologías hay en el mercado? ¿Cuál se adapta mejor a la empresa? ¿Es fácil de integrar con otras tecnologías web? ¿Tiene rendimiento? ¿Es fácil de cambiar si se vuelve obsoleto?

Showroom

¿Cómo sabrán los equipos cuáles componentes están disponibles y sus variantes? ¿Cómo debe ser la documentación? ¿Es posible mostrar una demostración del funcionamiento del componente para que sea fácil de usar? ¿Cómo instalar un componente en un proyecto?

Breaking Changes y updates

¿Cómo evitar lanzar un Breaking Change en nuevas versiones? ¿Cómo estructurar el código de un componente para que sea sencillo crear un nuevo parámetro? ¿Qué pasa si es necesario cambiar algún atributo CSS para satisfacer una demanda específica?

Comunicación (cambios, nuevos componentes, bugs)

¿Cómo se comunicarán los nuevos componentes y los nuevos cambios a los equipos de proyecto? ¿Cómo mantener un historial de errores resueltos por cada componente? ¿Qué pasa si un equipo quiere crear su propio WebComponent?

Calidad

¿Deberían los componentes tener pruebas automatizadas? ¿La tecnología elegida tiene reglas específicas de análisis estático para ella? ¿Cuáles tecnologías se pueden utilizar para el análisis estático local? ¿Es posible realizar un análisis estático de elementos específicos de la tecnología elegida y enviar los problemas encontrados a Sonarqube?

Tranquilo/a, todas las preguntas anteriores tienen respuesta. Fueron meses de mejora y quiero detallar aquí el caso de uso para ayudarte a tomar las mejores decisiones para una posible implementación.

Hoy este proyecto está en producción en más de 100 aplicaciones (hasta la redacción de este artículo) dentro de una gran empresa en las más variadas tecnologías web.

Soluciones con WebComponents

Organización

Este es uno de los primeros detalles en qué pensar, cómo consumirán los proyectos y cómo se estructurará todo este código. En esta empresa ya había una biblioteca construida por ellos en Angular, pero ésta ya tenía algunos problemas:

  • Solo se podía instalar en aplicaciones Angular (la empresa también usaba React, Angular.js y .Net para Front-end).
  • Al instalar esta biblioteca, los desarrolladores introdujeron en la aplicación un paquete de 12 componentes diferentes, ya sea que lo usaran o no, lo que terminó inflando el paquete final para nada.
  • La tecnología fue obstinada, es decir, si Angular se volviera obsoleto, la biblioteca tendría que ser reescrita para otra tecnología, haciendo que los proyectos que la usaban también tuvieran que ser reescritos.
  • Atascado con la estructura de versiones de Angular. Tan pronto como los proyectos actualizaron la versión, la biblioteca también necesitaba actualizarse, por lo que era necesario que existieran varias versiones de la biblioteca (para aquéllos que ya han actualizado y para aquéllos que aún no lo han hecho).

La primera decisión toma fue: Cada componente tendrá su propio repositorio

Este cambio ya generó algunas grandes ventajas:

  • La aplicación solo instala lo que necesita.
  • Si necesita hacer algún cambio, no es necesario generar una nueva versión con todo (más rápido para generar nuevas versiones).
  • La documentación es fácilmente accesible y estandarizada por readme.md.
  • Fácil de crear tags, changelog, branch.
  • Los problemas están centralizados en ese componente específico, por lo que es fácil mantener un historial.

Ya sabía cómo lo iba a organizar. Claro, esto terminaría generando decenas de repositorios en el GitHub de la empresa. Entonces ya dejé todo dentro de una organización específica que el GitHub empresarial nos permite crear.

Cuanto más pequeña fuera mi estructura, más fácil sería hacer un cambio y crear una versión.

Tecnologías e Interoperabilidad

Sabía que un problema que quería resolver era el acoplamiento que tenía esta empresa con la plataforma Angular, que dejaba fuera los proyectos que no eran de Angular y siempre obligaba a mover un elefante cuando el equipo de Angular generaba una nueva versión. Solo por curiosidad: cuando entré a trabajar en la empresa, Angular estaba en la versión 9, pero era necesario mantener las versiones 6, 7, 8 y 9 de la biblioteca, porque actualizar los proyectos era más difícil que cambiar la biblioteca y esto empeoraba con cada nueva versión).

Lo primero: elegí una tecnología agnóstica que, al final de la compilación, me entregue solo JavaScript puro y no se lleve ningún remanente de la tecnología que se usó para escribir el código. Angular se puede usar para crear WebComponents, pero su sistema de versionado era de 3 versiones por año porque son una plataforma gigante que hace de todo (http, formularios, rutas, etc.) y solo necesitaba una tecnología para WebComponents. Se consideraron las siguientes:


Estas 8 tecnologías fueron escogidas para someterlas a un análisis FODA y luego del análisis las separé en dos grupos: las librerías que fueron creadas exclusivamente para WebComponents (si bien es posible crear aplicaciones, fueron creadas para un propósito específico) y las que fueron creadas para manejar aplicaciones web completas.

Descarté todo lo que no estuviera enfocado a WebComponents, porque tardaron en incluir algo nuevo para los componentes y tuvieron que preocuparse por todo un ecosistema estructural. El enfoque estaba pensando en tomar algo pequeño para transformar el código en un WebComponent.

Entre estos 4 más famosos, me di cuenta de que el mantenimiento, la comunidad y la madurez de las bibliotecas Hybrids y Riot no eran tan buenos, principalmente porque no había una gran empresa que se ocupara del repositorio. StencilJS tiene el equipo de Ionic Framework y LitElement es del equipo de Google, ambas muy buenas tecnologías, maduras y con una comunidad lo suficientemente grande como para saber que ya está siendo utilizado en producción por miles de personas.

Al final del análisis, aun encontrando a LitElement como la mejor opción por ser propiedad de Google y contar con varias actualizaciones, la tecnología elegida fue StencilJS por dos motivos específicos:

  1. Sería fácil de implementar en toda la empresa (Stencil usa TSX además de React, Typescript y anotaciones como Angular), por lo que tendría una curva de aprendizaje baja para los desarrolladores que ya están en la empresa.
  2. Ya había muchos ejemplos de componentes escritos dentro del repositorio de Ionic Framework, todos reescritos en Stencil en la versión 4, lo que podría ayudar mucho a evitar problemas ya resueltos por ellos.

Una gran ventaja que también se encuentra en Stencil es su patrón Lazy Load, que carga partes del WebComponent según sea necesario, lo que mejora el rendimiento.

Entonces vino la segunda decisión tomada: StencilJS como herramienta para crear componentes.

Showroom

Una preocupación que tenía desde el inicio era la Comunicación.

Necesitaba hacer que los equipos de desarrollo quisieran usar el nuevo patrón y los nuevos componentes, para que siempre lo necesitaran cuando hubiera algo nuevo y los componentes fueran fáciles de usar.

Si los equipos del proyecto no usaban los componentes por alguna razón, ese podría ser el fracaso de este proyecto, por lo que necesitaba crear un WebComponents Marketplace.

Entonces, el primer paso fue diseñar un Marketplace:

Por motivos de fuerza mayor no puedo mostrar el Marketplace real, por lo que comparto este mockup.

Este Marketplace se creó en las páginas de GitHub para empresas, pero al final, es solo una aplicación web que se conecta a GitHub para obtener los datos. Los puntos destacados son:

  1. En otro repositorio (lo llamaré repositorio de control) creé solo para mantenerla una lista con los datos de todos los componentes que tenemos (así que, con cada nuevo componente, solo necesitaba hacer un nuevo compromiso que se reflejaría en el menú automáticamente).
  2. Este es el espacio de documentación. Aquí realizo una llamada a la API de GitHub y voy al repositorio de componentes para obtener el archivo README.MD (donde debería estar la documentación del componente).
  3. Aquí es donde estará la demostración con el componente funcionando. Cada repositorio de componentes debe tener un archivo demo.html del que Marketplace extraerá el contenido. Los binarios de los componentes se almacenaron en un repositorio central (también expuesto con las páginas de GitHub) en el que Marketplace simplemente agrega una importación en el HTML y comienza a funcionar.
  4. Headercon enlaces útiles, centralizando así los enlaces a Sonar, Pipeline y Artifactory.
  5. Aquí también fue muy útil agregar la cantidad de problemas en Github, así ya sabría si el componente tiene algún problema pendiente por resolver. (Más tarde también agregué este número al lado de cada elemento del menú, para una fácil identificación).

Estructura final:

  • Repositorio 1: marketplace (la aplicación Marketplace, en este caso realizada en Angular).
  • Repositorio 2: marketplace-control (donde se encuentra un archivo .json con todos los componentes y su información).
  • Repositorio 3: marketplace-components (los binarios de los WebComponents).
  • N Repositorios: los repositorios de WebComponents (de donde obtenemos la documentación y la demo).

Con todo configurado, el Marketplace rara vez necesita mantenimiento, ya que todo lo necesario está en repositorios externos \o/.

Y con esto doy por concluida la primera parte de este artículo. En la siguiente parte, te enseñaré cómo evitar los cambios de ruptura en los componentes y cómo mejoramos la comunicación utilizando también los recursos de GitHub.

Mientras tanto, te invito a conocer mi GitHub.

¡Saludos!

⚠️
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Revelo.

Revelo Content Network da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.