Si su empresa fabrica varios productos con el mismo estilo, un día se le ocurrirá la idea de crear una biblioteca con un código común. Por ejemplo, con componentes de IU, un servicio de autorización o para trabajar con API de terceros. Quizás se pregunte: ¿quién debería admitir este código? ¿Cómo comunicar los cambios a los usuarios? Después de todo, ¿cómo logras que usen tu biblioteca?
Desde 2015, he estado trabajando en Tinkoff en el departamento de servicios empresariales. Durante este tiempo, nuestro equipo ha crecido de 3 a más de 60 desarrolladores, y el ecosistema de Tinkoff Business ha crecido de 3 a 50 aplicaciones web. En diferentes etapas de nuestro desarrollo, abordamos el trabajo con código común de diferentes maneras, y quiero hablar sobre esto en este artículo.

Fundación: barata y alegre.
Entonces, avance rápido hasta 2015. Tenemos solo tres aplicaciones web: servicios de administración de efectivo, proyecto de nómina y panel de control. Y como muchos desarrolladores.
Las interfaces de la aplicación se realizan con el mismo estilo, y el código general se mueve a la biblioteca de Foundation en un repositorio separado. La biblioteca no compila, y, estrictamente hablando, no hay nada que compilar allí, todo el código en ES5 no se publica en npm, sino que está conectado por el nombre de la rama en package.json. Se crearon ramas de lanzamiento de Foundation separadas para lanzamientos de productos para corregir el estado. Si olvidamos arreglar la rama de la Fundación, con la revisión resultó que la Fundación había cambiado y la versión de la revisión simplemente no iba a funcionar.
Así es como se veía la conexión de Foundation en package.json:
"dependencies": { ... "sme-foundation": "git+https://stash_url/sme-foundation.git#develop" ... },
El principio principal de la biblioteca en este momento es la propiedad general del código.
Si una característica del producto requería una revisión de la Fundación, el desarrollador de la característica lo hizo él mismo. Y si eran incompatibles con la versión anterior, él también gobierna el uso de este código en todos los proyectos. Lo mismo era cierto para la refactorización a gran escala: si desea refactorizar un componente y cambiar su API, por favor, pero al mismo tiempo, realice todos los usos.
Si desea reutilizar en un proyecto lo que ya está en otro, tampoco es un problema, simplemente llévelo a la biblioteca.
Afortunadamente, no había mucho código. Este enfoque funcionó muy bien para tres, cuatro, cinco proyectos ... y tuvo una serie de ventajas:
- El código común estaba en un lugar y se reutilizaba en proyectos.
- Proyectos desarrollados más rápido.
- La biblioteca estaba creciendo.
- Todos tenían conocimiento tanto del código general como de los proyectos, lo que hizo que la revisión y la adopción de decisiones arquitectónicas fueran más eficientes.
- La necesidad de refinar el código general no bloqueó el desarrollo de características.
En este punto, teníamos un mínimo de documentación: algunas pruebas unitarias y JSDoc. Para los componentes de la interfaz de usuario, no había suficiente visualización visual de la ventana, y vimos una solución barata y rápida: la interfaz de usuario de demostración. De hecho, fue una aplicación angular, en cuyas páginas se insertaron los componentes y el marcado correspondiente.

En 2019, es poco probable que haga lo mismo. Pero aquí está lo que se puede aprender de esta historia:
- Compartir código común funciona muy bien para equipos pequeños.
- Incluso si solo hay tres de ustedes, no sean perezosos para hacer un código repetido, esto está disponible para equipos de cualquier tamaño.
- Incluso una página normal con una lista de componentes puede simplificar enormemente su vida.
Con el paso del tiempo, el ecosistema y el equipo de desarrollo de Tinkoff Business crecieron. Cuando hubo más de una docena de proyectos, este enfoque dejó de funcionar.
Cambiar los componentes comunes se ha vuelto demasiado costoso. El desarrollador de un proyecto ya no estaba familiarizado con todos los demás proyectos, la búsqueda del uso de componentes y los cambios se volvieron más complicados. El tiempo para implementar nuevas características que afectan a la Fundación creció.
Los nuevos desarrolladores no tenían una imagen completa de lo que se hizo y cómo se usó.
Cambiar la API del componente fue aterrador, debido a esto, los componentes de Frankenstein aparecieron con una gran cantidad de parámetros de entrada.
A veces esto condujo a una
inconsistencia en la experiencia de usuario . Detalles como trabajar con el teclado, trabajar con foco, se implementaron de manera diferente en diferentes componentes. Y en algún lugar, no se implementaron en absoluto, porque los desarrolladores se centraron en las características comerciales.
Otros proyectos angulares aparecieron en la empresa, y sugerimos que también usen nuestra biblioteca. Al principio, incluso estuvieron de acuerdo ... Pero tan pronto como se necesitaron mejoras, nos encontramos en una situación difícil: todos nuestros desarrolladores están ocupados con sus proyectos, y nuestros colegas no tienen motivación para tratar con la biblioteca de otra persona.
Todos eran responsables de la Fundación y nadie en particular, y esto no era adecuado para los colegas.
UI Kit y un nuevo enfoque para la organización del trabajo
Cuando se trataba de 2017 sobre el rediseño y el nuevo kit de interfaz de usuario, comenzamos a desarrollar nuevos componentes de una manera diferente. Para empezar, tenemos un equipo dedicado.
El equipo
Seleccionamos a tres personas de los equipos de productos y dijimos: "Ahora estos muchachos están haciendo componentes de interfaz de usuario para otros proyectos".
¿Qué dio el equipo dedicado?
- En primer lugar, en poco tiempo preparamos los componentes básicos para los equipos de productos. Dos semanas después del inicio del desarrollo, los colegas recibieron lo más necesario. Y luego desarrollamos la biblioteca, centrándonos en las prioridades de los clientes.
- El equipo dedicado se centró específicamente en componentes y UX. Nuestra tarea consistía en crear componentes que fueran cualitativos, tanto desde el punto de vista del usuario final de las interfaces (sangría correcta, contrastes, trabajar con el teclado; esto no era una bagatela para el equipo de ballenas), y desde el punto de vista de los desarrolladores de equipos de productos (API consistente, conexión conveniente, extensibilidad) .
- Un equipo dedicado es una responsabilidad. Si se encuentra un componente en un componente, el desarrollador del producto no se quedará solo con él. Los errores críticos se corrigen con alta prioridad y se prepara una revisión, mientras que los errores menos críticos se corrigen en el orden de prioridad. Vale la pena señalar aquí que antes de la aparición del equipo resaltado, los defectos que no eran críticos para los equipos de productos (por ejemplo, el color del marcador de posición en la entrada y en la selección son ligeramente diferentes) podrían permanecer en el trabajo atrasado durante mucho tiempo, dando paso a las características comerciales. Pero para el equipo de ballenas, la apariencia de los componentes es la primera prioridad.
Si la experiencia en componentes se concentra en un equipo, ¿cómo enseñar a otros cómo usar estos componentes? Para esto hemos hecho una excelente documentación.
La documentación
La idea de rediseñar nuestro stand de demostración ha estado en el aire durante mucho tiempo, y el desarrollo de una nueva biblioteca lo ha hecho posible.
Luego, Storybook for Angular aún no se ha lanzado, así que seguimos nuestro propio camino. Es lo mejor: nuestra propia implementación no limitó nuestra imaginación, pudimos hacer absolutamente todo lo que queríamos.
Y esto es lo que hicimos:
- Se agregó información sobre la biblioteca en su conjunto: una descripción paso a paso de cómo se conecta y una lista de navegadores compatibles.

- Preparamos una descripción detallada de cada componente: por qué es necesario, cómo está conectado, qué parámetros de entrada-salida admite (con la capacidad de pincharlos, a la Storybook), ejemplos de uso típico, una lista de componentes similares.


- Se agregó una lista de proyectos en los que se usa este componente.

- Comenzaron a recopilar estadísticas sobre el uso de la ballena en diferentes proyectos: qué proyectos están conectados, qué versión, cuántos componentes se utilizan, qué versión del angular y la ballena en cada proyecto; esta información se utiliza para planificar cambios incompatibles y se niega a admitir versiones antiguas del marco. Una descripción de la herramienta que recopila estas estadísticas merece un artículo separado.

- Versiones agregadas: vea la documentación de cada versión lanzada anteriormente del Kit de IU.

Por supuesto, todo esto no apareció de inmediato, sino que evolucionó.
Dentro de nuestro departamento, un equipo dedicado y documentación sería suficiente. Los colegas están acostumbrados a usar un código común, conocen a los desarrolladores del kit de interfaz de usuario y, en general, son muy leales.
Pero el diseño del kit de interfaz de usuario en sí se posicionó como común para todos los productos de la compañía, lo que significa que docenas de equipos necesitaban los mismos componentes, desde proyectos internos de recursos humanos hasta WebOffice, un sistema de trabajo para decenas de miles de empleados remotos. Por lo tanto, el equipo de ballenas se enfrentó a una tarea más amplia: crear un producto interno de alta calidad que usarán todos los equipos de Angular.
En general, los colegas de otros departamentos eran positivos, pero aún tenían algunas dudas: si las características que necesitaban se desarrollarían lo suficientemente rápido, si serían de alta calidad ... Alguien ya había comenzado a fabricar componentes por sí mismo.
Para resolver estas dudas, organizamos el trabajo de la manera más transparente posible.
Transparencia
Si saca un solo pensamiento de este artículo, deje que sea la siguiente idea: para que una biblioteca tenga éxito, no es suficiente hacer buenos componentes. Debe ser lo más transparente y orientado al cliente posible. En este caso, los clientes son desarrolladores de productos finales.
Debe, por todos los medios posibles, transmitir a sus colegas lo que está haciendo, por qué y cómo usarlo.
¿Qué herramientas utilizamos?
Lanzamientos regulares y demos. La primera demostración tuvo lugar dos semanas después del inicio del desarrollo y luego se realizó semanalmente, el día del próximo lanzamiento. A veces había muchas características nuevas, y a veces solo correcciones de errores. Hicimos una demostración sin importar qué.
Mirando hacia el futuro, diré que el trabajo principal se ha completado, la API se ha estabilizado y el equipo ha cambiado a la alternancia de lanzamientos, uno con características, otro con ediciones y mejoras, y la demostración se lleva a cabo solo en lanzamientos con nuevas características.
Registro de cambios Introdujimos los compromisos convencionales y la generación de un registro de cambios a partir de ellos, lo que simplificó enormemente la transición a nuevas versiones para los equipos.
Equipo "receptivo" . Como todos los equipos, tenemos nuestro propio canal en Slack, esto no es nada nuevo. De hecho, incluso tenemos dos canales: uno para la comunicación dentro del equipo y otro para los usuarios: respuestas a preguntas, anuncios, encuestas, realización de demostraciones y otras actividades.
Es importante que las preguntas entrantes estén realmente resueltas. Algunas de las preguntas son complicadas en el caso, algunas señalaron los vacíos en la documentación (o háganos saber que no todos la leen). Y a veces los recién llegados a Angular escribieron sobre sus dificultades. El equipo de ballenas con igual preparación ayudó a todos, no siendo flojos para telefonear si el problema no se resuelve en el chat, o incluso para descargar el código de otra persona. Naturalmente, tales comunicaciones pierden tiempo a los desarrolladores, pero esto es parte del trabajo en la biblioteca.
Ahora hay más de 200 usuarios en el canal de ballenas, y muchas preguntas se resuelven sin la participación de los desarrolladores de ballenas: los colegas comparten sus experiencias y responden las preguntas de los demás.
Boletines con una lista de cambios después del lanzamiento. Su público objetivo son los desarrolladores, gerentes y diseñadores de productos. En los boletines informativos, los cambios se describieron simple y fácilmente, lo que no siempre es posible en Changelog, y contenían imágenes de "fue / se convirtió". Todavía estoy seguro de que esta es una gran herramienta, pero fue difícil preparar resúmenes claros y de alta calidad todas las semanas. Después de un tiempo, dejamos de enviarlos, pero quizás volvamos a esta práctica.
Las encuestas de usuarios proporcionan una visión externa y revelan debilidades. Por ejemplo, de acuerdo con los resultados de la próxima encuesta, aprendimos que la mayoría de los colegas están totalmente de acuerdo en que los desarrolladores del Kit de interfaz de usuario están listos para ayudar, lo que significa que estamos haciendo todo bien en esta dirección. Pero con la declaración "Nuevos componentes se están desarrollando rápidamente", menos encuestados estuvieron de acuerdo. ¿Qué hacer con esos resultados? Por un lado, llame la atención de todos los miembros del equipo y trabaje en los puntos débiles. Por otro lado, trabaje con los usuarios. Si la velocidad es importante, preste más atención a la explicación de dónde provienen dichos términos.

Las encuestas incluyeron preguntas abiertas como "¿Qué podemos mejorar?" Debo decir que nuestros colegas nos dieron algunos consejos valiosos: por ejemplo, para hacer el botón Copiar para ejemplos de código o para enseñar a nuestras clases las fechas para trabajar con unixtime.
Rol del equipo
Arriba, ya escribí sobre el "equipo receptivo", que decide mucho para el éxito de la biblioteca en toda la empresa. Quiero enfatizar esta idea nuevamente y hablar sobre dos prácticas relacionadas.
Deber . En algún momento, la comunicación con los colegas se hizo tan grande que la introducción del deber parecía inevitable. Así es como trabajan los equipos de servicio en Tinkoff. Una vez al día, dos días, una semana, uno de los miembros del equipo está de servicio. Él monitorea el canal, responde preguntas y toma la mayoría de las comunicaciones, mientras que sus compañeros de equipo no se distraen con el apoyo.
No hemos llegado a este punto, y con el tiempo la necesidad ha desaparecido. Sin embargo, otros equipos de servicio reciben ayuda.
Auditoria Nadie conoce mejor los componentes de una ballena que el equipo que los desarrolla. Y durante dos años de desarrollo, los muchachos también han acumulado una excelente experiencia en Angular. Ahora estamos presentando la práctica de "auditorías del equipo de ballenas". Los chicos se conectan a la revisión de proyectos de productos, y también ven los productos finales y su código. Su objetivo es identificar el mal uso, refinar la documentación y hacer una lista de buenas y malas prácticas. Hablaremos sobre lo que sucederá la próxima vez.
Desafíos y compromisos
Como cualquier proceso con una gran cantidad de partes interesadas, el desarrollo de una biblioteca común nos obliga a buscar compromisos.
No fue fácil para nosotros encontrar un equilibrio entre la calidad del código y la estabilidad de la API. Por un lado, el diseño cambió al comienzo del trabajo: aparecieron nuevos componentes o nuevos estados de componentes antiguos; algo, por el contrario, era obsoleto y aserrado. Por otro lado, la visión de los desarrolladores sobre el componente correcto API estaba cambiando. Todo esto condujo inevitablemente a cambios importantes. Pero el número de usuarios de la biblioteca creció y nuestros cambios importantes les causaron grandes inconvenientes.
Encontramos un compromiso: hacer cambios de última hora no más de cada quinta versión, es decir, una vez cada cinco semanas. Por ejemplo, dichos cambios podrían requerir versiones 0.50, 0.55, 0.60. Pero la transición de 0.50 a 0.51 no requirió ningún esfuerzo. Esto continuó hasta el lanzamiento de la versión estable 1.0.0. Ahora la API es estable y todos los cambios a gran escala se posponen a 2.0.0 en un futuro indefinido.
Varias veces, cambiar a una nueva versión requirió mucho trabajo de rutina: cambiar el nombre de los prefijos, cambiar las importaciones de iconos y similares. Para tales casos, hemos implementado scripts de migración.
Conclusiones
Este artículo describe nuestros cuatro años de experiencia trabajando con bibliotecas de código compartido. ¿Qué conclusiones sacamos?
- Incluso un equipo pequeño no debería soportar la duplicación de código. Eliminar el código en la biblioteca es una solución accesible para todos.
- La propiedad conjunta del código común funciona bien para equipos pequeños, hasta 10 proyectos son usuarios de la biblioteca.
- Con el creciente número de proyectos o desarrolladores involucrados, es más conveniente resaltar un equipo con un enfoque en el código común.
- Una parte importante del trabajo de un equipo dedicado es la comunicación con los usuarios: demostración, capacitación, ayuda, documentación.
- No tenga miedo de pensar más e invertir tiempo en herramientas. En nuestro caso, este es un escaparate conveniente con documentación y un analizador para usar componentes.