WebComponents a nivel empresarial - parte 2
Álvaro Junqueira. En el artículo anterior, vimos cómo una gran empresa que usaba bibliotecas y marcos de trabajo patentados y con opiniones para crear sus componentes de interfaz de usuario comenzó a transformarse cuando introdujeron WebComponents como su pila principal.
En esta segunda parte, veremos los últimos tres grandes desafíos que se encontraron y mitigaron durante el transcurso del proyecto: cómo lidiar con Breaking Changes, cómo comunicarse y crear una comunidad de desarrolladores en la empresa (para informar errores o solicitar nuevas características) y cómo mantener la calidad evitando que las nuevas versiones rompan los proyectos heredados.
Un breve resumen:
- Primero definimos cómo deben organizarse los repositorios: se eligió un repositorio para cada componente para no crear dependencias (lo que significa un pipeline para cada uno también).
- El segundo fue la elección de la tecnología y, tras algunos enfrentamientos entre LitElement y StencilJS, se optó por StenciJS porque la empresa se identificaba más con la estructura.
- Y el tercer punto y más importante para el día a día: la creación de un Marketplace que recabaría la documentación y mostraría una Demo de cada componente, todo ello online y conectado al GitHub de la empresa.
Los primeros tres desafíos identificados fueron mitigados y permitieron crear y entregar los componentes. Sin embargo, algunos puntos debían ser discutidos, porque para cualquier tecnología que desee incluir a gran escala, necesitaría tener algún control de calidad para estos componentes.
Ahora comenzamos a explorar los últimos tres (y no menos importantes) puntos:
- Cambios y actualizaciones de última hora.
- Comunicación (cambios, nuevos componentes, bugs).
- Calidad.
Actualizar, Comunicar y Revisar
Cambios y actualizaciones de última hora
Crear un componente que encapsule un texto de entrada parece relativamente simple, ¿no es así? Bastaría con crear un CSS que lo dejara con el estilo de la empresa, pero no es tan sencillo. Algunos componentes son muy importantes ya que recibirán mucho estilo con el tiempo. Muchas demandas de proyectos que necesitarán diferentes cosas para un solo componente. Si deseas brindar alguna ganancia a quien lo vaya a usar, el componente naturalmente comenzará a recibir algunas funciones.
Solo en esta empresa que uso como ejemplo, el componente que encapsuló el texto de entrada recibió las siguientes características:
- Posibilidad de incluir un icono en el prefijo (lado izquierdo).
- Posibilidad de incluir un icono en el sufijo (lado derecho).
- Solo acepta números.
- Mostrar el texto abajo para obtener ayuda o cuando se encuentre en un estado no válido.
- Mostrar un icono de ayuda junto a la etiqueta, para obtener más información sobre el campo.
Estas y muchas otras propiedades que se han desarrollado con el tiempo, porque encapsularlas en el componente tendría más sentido que tener varios proyectos implementando lo mismo.
A medida que llegaban las solicitudes de funciones, la preocupación era solo una: no puedo romper las aplicaciones que ya están funcionando. Si alguien necesita actualizar la versión del componente para resolver un error, el diseño y la implementación del componente no podrían fallar (y recibir nuevos errores).
La política que se creó fue, primero, utilizar la Versión Semántica (Semver):
Es decir, solo en casos excepcionales en los que no podemos obtener un nuevo parámetro y es necesario lanzar un cambio importante, cambiaríamos la versión principal de un componente. Siempre que se puedan crear parámetros, el componente solo debe cambiar a una versión secundaria o parche.
Cambiar una versión principal significaría tener que comunicarse con todos los desarrolladores y documentar lo que se necesita hacer para la migración.
Entonces, junto con la regla de usar estrictamente Semver en los componentes, se creó la máxima: trate de evitar la versión 2 tanto como sea posible, apéguese siempre a la versión 1 de un componente, cree parámetros.
Comunicación (cambios, nuevos componentes, errores)
Bien, digamos que en un momento dado no será posible crear un parámetro o que toda la empresa está pasando por un rediseño y todos los componentes necesariamente cambiarán a una versión 2. O incluso aparece un error importante y es necesario informar a todos para actualizar los componentes. Y ahora, ¿cómo debemos actuar?
Después de haber creado el Marketplace, sabía que aún necesitaba mantener informada a la comunidad de desarrolladores y que se tenía que organizar para documentar y recibir errores y solicitudes de nuevas funciones.
Changelog
Como ya había determinado que recibiría solicitudes de los desarrolladores a través de problemas de Github, también decidí mantener un CHANGELOG.md para cada componente. De esta manera, pude cerrar los problemas al vincular un compromiso y mantener el historial de fácil ubicación de los cambios (elegí el formato que usa el equipo de Angular en los repositorios, ya que era simple de entender).
Blog
En esta empresa también usamos Confluence, como herramienta de documentación, esta herramienta ya viene con una funcionalidad de blog:
Creé una sección para que la comunidad de Front-end vea y reciba un correo electrónico cada vez que haya algo nuevo en el blog de Confluence. Con eso, con cada nuevo componente o funcionalidad importante, podría decirles a todos cómo usarlo y cómo acceder al enlace en Marketplace.
Noticias
Finalmente, le pedí a la empresa que creara un correo corporativo para el front end (esos que puedes incluir a varias personas en Outlook, enviando solo al grupo). Estaba agregando al grupo las personas que necesitarían recibir la información.
Para cada nuevo elemento, componente, cambio en el Marketplace, cambio en el Diseño, nueva iniciativa de Front-end o incluso para enseñar algo interesante o señalar enlaces externos para el estudio, crearía un correo electrónico, que tendría un contenido reflejado en el blog (el blog mantendría el historial y el correo invitaría a acceder y conocer más).
Esta noticia por correo electrónico fue la más exitosa, ya que llamaba a la gente para averiguar qué estaba pasando y, a menudo, recibí algunos comentarios directamente allí. La periodicidad de esta Noticia fue en promedio de 2 por mes.
Presentaciones para la comunidad de desarrolladores
Y por último, establecí que haría dos presentaciones a la comunidad sobre las novedades en el Front-end cada 6 meses.
La intención era mantener a la comunidad informada y comprometida, promoviendo así el uso de WebComponents de una manera que muchos proyectos heredados querían reescribir y nuevos proyectos querían usar. Cuanto más motivada estaba la comunidad, más comentarios recibí y más componentes descubrí que se podían hacer. Así evolucionó.
En estas presentaciones también surgieron dudas e ideas, que solo quienes están programando los proyectos todos los días conocen. También fue una forma de que mi área se actualizara y mostrara las novedades a aquellos que aún no lo habían visto (siempre hay rotación de desarrolladores y siempre habrá gente nueva que ni siquiera sabe que existe Marketplace).
Calidad
Eso es todo, los componentes están escritos, demostrados, siendo utilizados en la versión 1 por algunos proyectos nuevos, todos comienzan a probar y boom, alguien necesita el primer cambio a un primer componente.
¿Cómo puedo garantizar que en este primer cambio no afectaré algo en otro proyecto? ¿Me he anticipado a las situaciones de uso? ¿Me detuve a pensar en ello? ¿Qué tan fácil es cambiar mi componente? ¿El código es simple o complejo?
Dejé para el último tema lo que se debe pensar desde el inicio del desarrollo de un componente.
Cuando escribimos un componente solo para una aplicación, ya sabemos qué queremos de él, cuál es el comportamiento esperado, no nos preocupa si se podrá usar en otro proyecto que tenga otro propósito. ¿Cómo puedo garantizar (o al menos acercarme) que un cambio no romperá otros 80 proyectos a la vez y me causará un gran dolor de cabeza para hablar con todos? =u
La respuesta es un conjunto de puntos importantes:
- Análisis estático.
- Pruebas unitarias.
- Estructura mecanografiada.
- Estructura de CSS.
Explico lo que hicimos para cada punto, una vez que tengas estos puntos en tu cabeza y como regla general para crear un componente, tu vida será un 120% mejor.
Análisis estático
La empresa ya estaba usando Sonarqube para realizar análisis estáticos, lo que ya era un punto positivo, pero cuando elegí StencilJS, también vinieron algunas reglas específicas para ello.
Lo que hice primero fue configurar el ESLint en los componentes (después también creé un generador con Yeoman para ya crear un componente con todas las configuraciones necesarias para nosotros, incluido el ESLint y las reglas que definí).
Con ESLint configurado (no es la idea de este artículo mostrar cómo configurar ESLint en StencilJS, búsquenlo en Google), también instalé una biblioteca para algunos casos específicos que es propiedad del equipo de Ionic: https://github.com/ionic-team /stencil-eslint.
Solo necesitas configurar:
- En su paquete.json, cree un script para ejecutar eslint generando un archivo json al final, por ejemplo (en nuestro caso, los archivos tienen la extensión tsx para StencilJS):
Agregue esta tarea para que se ejecute en su tubería antes de ejecutar el análisis estático de Sonarqube.
En la configuración de Sonarqube (cada empresa lo pone en un sitio diferente) basta con añadir la propiedad para enviar el archivo json generado, por ejemplo:
Nota: puedes crear un formateador para ESlint para cambiar la gravedad de las reglas si es necesario. No olvides instalar el complemento ESLint para el IDE que usas, ¿eh?
Pruebas unitarias
Este tema, para los que ya conocen las pruebas unitarias, se explica por sí mismo, solo me gustaría exponer el punto porque este es uno de los más importantes. Al generar una propiedad, crea las pruebas unitarias necesarias para probarla e intenta imaginar diferentes escenarios para usar esta propiedad combinada con otras existentes.
Las pruebas unitarias te harán ver si no estás entregando algo nuevo y rompiendo algo que ya existe, evitando que esos 80 proyectos te llamen a la vez.
No hace falta decir que las pruebas unitarias DEBEN ejecutarse en el pipeline y debe detenerse si no se ejecutan correctamente, ¿verdad?
Estructura de Typescript y Estructura de CSS
Para tener un estándar, genera una estructura sobre cómo crearás tu código. Aquí, por ejemplo, mantenemos primero los métodos del ciclo de vida de StencilJS, luego los métodos privados, el método de representación siempre debe ser el último y así sucesivamente.
No hay una regla exacta sobre cómo va a hacer esto en este caso, lo importante es que los creadores del componente definan y sigan una regla, en este caso una revisión de código o una regla personalizada en ESLint ayuda mucho. En cuanto a la estructura CSS, aquí lo que mejor encajaba era el BEM (Block, Element, Modifier), porque es sencillo y usamos SCSS como herramienta.
Como verás en WebComponents, también se usarán muchas Variables CSS (CSS4) y mantenerlas organizadas y documentadas ayuda mucho, ya que en la compilación StencilJS genera la documentación (readme.md) automáticamente a partir de lo que toma desde dentro del componente
¡Eso es todo!
Muchas lecciones aprendidas y mucho por compartir. Era un proyecto que se podía afrontar de forma sencilla, pero hoy me doy cuenta de la adherencia y de lo bien que se está aprovechando. Vi que mis esfuerzos valieron la pena.
Esta empresa para la que trabajo es multinacional y este proyecto se ha convertido en un caso de éxito aquí en Bélgica. Ahora nos estamos expandiendo a otras sucursales en varios otros países, ya que la estructura está lista. Éxito y hasta la próxima \o/.
Álvaro Junqueira - https://github.com/alvarocjunq
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.