Arquitectura de frontend a escala para grandes organizaciones

(Daniel Ostapenko) ( 14 de octubre de 2020)

¡Hola! Quiero discutir contigo cómo administrar la arquitectura Frontend en grandes organizaciones. Me parece que no hay muchos artículos sobre este tema y no está bien explicado.

Por gran organización en este artículo, me refiero a empresas, en las que el número de ingenieros de front-end comienza a ser más grande que 15 y la empresa tiene al menos varios proyectos frontend.

No quiero hablar sobre problemas de gestión o asuntos de dominio empresarial, los que se ven comúnmente en empresas tan grandes, pero centrémonos solo en la arquitectura Frontend.

La arquitectura Frontend está involucrada en demasiadas áreas hoy en día, así que para empezar propondría dividirla en las siguientes secciones:

Esquema de arquitectura de frontend

1. Código visual

Empecemos por el tema más sencillo, en mi opinión, es el código visual de nuestras aplicaciones.

Lo más probable es que porque desarrollamos múltiples aplicaciones frontend en la misma empresa las queremos tener:

  • reconocimiento de marca
  • la misma UI / UX

Para lograr eso necesitamos tener un sistema de diseño. El equipo de diseño tiene que idear el sistema de diseño y seguir esas pautas de diseño en todos los diseños de productos futuros. Incluso esto ya es una tarea muy compleja y necesita muchas discusiones y alineaciones entre el equipo de diseño, los ingenieros y el producto.

Desde el punto de vista del front-end, necesitamos proporcionar una herramienta para implementar y para comparta este sistema de diseño con los ingenieros. Una buena solución para eso puede ser la creación del paquete npm, que será representado visualmente por un Storybook o alguna herramienta similar. En mi opinión, es muy importante tener un recurso web dedicado (con URL) con documentación sobre cómo usar este paquete. Este recurso web será utilizado por ingenieros de front-end y por diseñadores y puede ser un gran punto de referencia en conversaciones entre ellos.

Código visual

Resumen:

En este momento, tenemos un sistema de diseño y su representación en un paquete y documentación interactiva para él. Compartimos y adoptamos este paquete en todas nuestras aplicaciones frontales.

2. Estructura de código

Hablemos de un poco sobre ingeniería a diario. Implementamos nuevas funciones, arreglamos errores y refactorizamos el código si es necesario. Nos preocupamos por nuestro código base, tratando de hacerlo agradable y fácilmente comprensible. Pero, ¿qué pasa cuando empezamos a tener no 1, ni 2, sino decenas de pequeños o grandes proyectos en la empresa? Por lo general, las personas se agrupan en torno a algunos de los proyectos y comienzan a trabajar solo con este grupo de proyectos. Por nuestra naturaleza humana y el tiempo limitado, por lo general, no podemos ocuparnos de más de 2 a 3 o 5 proyectos en un período de tiempo. Por eso, naturalmente, comenzamos a tener esos grupos de influencias. Por cierto, gracias a la NASA por una foto tan increíble para mi analogía 😃

Grupos de influencias

Pero, empezamos a tener más y más casos, cuando las personas se han cruzado -Equipos colaboraciones, necesitan verificar el código y las soluciones de los demás, corregir algunos errores incluso en otras aplicaciones o agregar algo que necesiten dentro de alguna aplicación externa (externa para su grupo de influencia). La mala noticia: que este proceso está ocurriendo en las grandes empresas de forma casi incontrolada. Las buenas noticias: podemos ayudar a mejorarlo.

¿Cómo? Correcto. Al proporcionar la misma estructura de código , directrices de codificación y estructura para todos los proyectos en la empresa.

Profundicemos en lo que queremos decir con estructura de código:

  • La estructura de carpetas en el proyecto
    Cuando los ingenieros saltan a un nuevo proyecto por primera vez, con la misma estructura de carpetas que en su proyecto, donde saben que todo ayuda mucho para navegar y buscar.
  • Archivos de configuración o de apoyo
    Archivos como package.json, .gitignore, .editorconfig, webpack.config, etc. Deben estar siempre en el mismo lugar, en todos los proyectos, lo mismo se conecta a los archivos de configuración de las pruebas o archivos CI si es necesario.
  • Ubicación fija de los tipos de archivos
    Si la ubicación de los mismos tipos de archivos es la siguiente siempre la misma estructura también funciona muy bien. Por ejemplo, si la carpeta del componente siempre tiene un style.css archivo:
/Component
--/Component.tsx
--/style.css
--/index.ts
  • Estructura interna de los componentes
    La estructura dentro de los archivos debe ser la misma: orden de importaciones, exportaciones, posición de la función pública , tipos, etc. En cada tipo de archivo, debe saber qué esperar.
  • Convenciones de nomenclatura
    Esto incluye nombres de carpetas, archivos, variables, funciones, clases, tipos, etc.
  • Convenciones de codificación
    En general, diría que las convenciones de codificación son una sección muy amplia, pero aquí solo quiero incluir cosas que no encajan en el resto de las secciones, como ; o not ; 😁 y similares .

La misma estructura de código y el conjunto de herramientas del proyecto en la práctica están muy unidos er y ayudarse mutuamente a coexistir. Por conjunto de herramientas me refiero a herramientas CLI (arranque del proyecto, linting, pruebas, etc.), extensiones IDE, etc. Discutiremos el tema del conjunto de herramientas en las siguientes secciones.

Estructura de código

Resumen:

Después de aplicar esta sección y adoptarla, deberíamos tener todos los proyectos de la organización con la misma estructura de carpetas, pautas de nombres, estructura de archivos, etc. Todos los desarrolladores idealmente puede saltar a cualquier otro proyecto y no perderse por completo allí. Este «completamente perdido» también está muy relacionado con la pila de tecnología que se utiliza dentro del proyecto, así que hablemos de ello.

3. Pila de tecnología

Similar al anterior , queremos tener una pila de tecnología unificada en todos los proyectos de la organización. El razonamiento para esto es muy similar: queremos que nuestros ingenieros se sientan cómodos con todos los proyectos de la empresa.

En los proyectos de Frontend, los componentes de la pila tecnológica pueden ser: marco, en función de que se construya el proyecto, el lenguaje principal, el procesador de estilos, capa de datos (por ejemplo, Apollo), administración de estado, pruebas, codificación de código, sistema de compilación y otros.

Por supuesto, en todas las reglas hay excepciones. Y en este tema, también me gustaría hacer un comentario, que a veces algunas tecnologías encajan extremadamente en algunos proyectos específicos, incluso si esas tecnologías no son parte de la pila tecnológica global de toda la empresa. Pero aún así, cada vez que esta idea surge para alejarse de la tecnología pany tech stack debería pensarlo dos veces porque el costo de respaldar estas cosas es muy alto, por lo que los beneficios tienen que ser dramáticos.

Mencionemos aquí algunas tecnologías genéricas que pueden encajar ahora en la mayoría de los proyectos por supuesto, solo cubre una parte de la tecnología real, pero puede ser un buen punto de partida para alguien 🤷):

Stack

Una vez que definimos el stack tecnológico en nuestra empresa y lo acordamos, también existen otros pilares muy importantes del éxito .

Primero, necesitamos escribe la pila de tecnología en el documento. El documento, que debe compartirse bien y fácilmente entre ingenieros , para que siempre puedan darse un enlace entre ellos como prueba.

En segundo lugar, debemos volver a escribir y compartir el documento con la forma cómo se deben iniciar y arrancar los nuevos proyectos, mediante el uso de la pila tecnológica definida .

Tech Stack

Resumen:

Después de que implementamos y adoptamos todo lo que «hemos mencionado anteriormente, debería tener todos sus proyectos en la organización para compartir la misma pila de tecnología. Idealmente, sin diferencias. No idealmente, con diferencias insignificantes. Si agregamos también la sección anterior, el código, las carpetas y la estructura de archivos también deberían ser casi idéntico en sus proyectos.Por lo tanto, navegar por cualquier proyecto debería ser una tarea muy fácil. Bueno 😊

4. Herramientas

Este tema es muy importante. Usamos algunas herramientas adicionales ahora en casi todas partes: para crear aplicaciones, CI, generadores de componentes y mucho más. Por eso veo si podemos elegir las herramientas correctas para nuestros proyectos; es crucial. Buenas herramientas frente a malas herramientas (o ninguna herramienta), es lo mismo que una comparación entre la automatización y las pruebas manuales .

En las secciones anteriores hablamos sobre la pila tecnológica y la estructura del código y mencionamos que necesitamos escribir mucha documentación para que la gente los siga. Pero el conjunto de herramientas correcto puede brindarle la oportunidad de automatizar siguiendo las pautas de su empresa .

Para Por ejemplo, si tiene un estilo de codificación específico, puede darles a las personas el conjunto de herramientas de linting, que de forma predeterminada sigue esas reglas. Si tiene la pila tecnológica definida, entonces una buena herramienta CLI le dará la oportunidad de iniciar un nuevo proyecto con esas tecnologías específicas de su pila tecnológica en su lugar.

Intentemos discutir qué partes de su arquitectura de interfaz se puede cubrir con herramientas:

  • Estilo y estructura del código
    Como comentamos anteriormente, esto se puede automatizar fácilmente con herramientas
  • Iniciación del proyecto
    No » No es necesario crear una nueva estructura de proyecto, instalando manualmente todos los paquetes que sean necesarios, etc.
  • Generación de componentes
    La mayoría de las veces, algún componente de su aplicación no contiene un solo archivo, por lo que la creación de archivos, vincularlos / importarlos puede llevar tiempo, por lo que esto se puede automatizar.
  • Iniciar y compilar
    Por supuesto, lo más obvio para mate: cómo compila o inicia su aplicación.
  • Pruebas
    El proceso de construcción de su aplicación para pruebas y ejecutando todo tipo de pruebas: unidad, integración, etc.
  • Gestión de dependencias
    Como sabemos, alrededor del 80\% de nuestro código ahora son dependencias. Por lo tanto, debemos mantenerlos actualizados y administrar eso en una gran empresa no es algo fácil de hacer.
  • Dependencias entre proyectos
    Lo más probable es que nuestros proyectos no estén funcionando de forma aislada y podrían depender de otros proyectos o ser una dependencia para algún otro proyecto, por lo que es posible que necesitemos algunas herramientas para facilitar el proceso de vinculación. desarrollar en una combinación de varios proyectos (como Bit , por ejemplo), etc.
  • CI
    CI es una parte esencial de nuestro conjunto de herramientas de uso diario y la automatización y unificación puede ser un trabajo muy beneficioso para su organización.

Si no desea desarrollar un nuevo conjunto de herramientas propio, puedo recomendar el NX toolset , como uno de los candidatos más interesantes. También , parece que los creadores de Babel han hecho una solución similar, que es posible que desee comprobar: Roma . Esas herramientas no cubren todo, sino una gran parte de lo que hablamos, por lo que pueden ser un buen punto de partida.

Herramientas

Resumen:

Imagínese lo grandiosa que puede llegar a ser nuestra arquitectura después de haber terminado y adoptado todas las secciones 🧙

Cada proyecto es el mismo y se mantiene y administra mediante el conjunto de herramientas unificado. Cada proyecto puede comenzar y construir de la misma manera. Los nuevos componentes se generan en el mismo lugar y con las mismas pautas de nomenclatura.

¿Pero es así de «dulce» o tiene desventajas? Como con cualquier solución, tiene desventajas. Uno de ellos: se necesita algo de tiempo para incorporar nuevos ingenieros a su empresa. Pero si todo se hace de una manera muy natural (como la gente ya se acostumbró en otras herramientas existentes) y se documenta, entonces esto no se convierte en un gran problema cuando se compara con los beneficios de la velocidad de desarrollo, una oportunidad para que los ingenieros trabajen con cualquier base de código fácilmente, etc.

5. Producción

En esta parte de la arquitectura de la interfaz, los ingenieros se ocupan menos de ella.Tal vez porque no está conectado con la codificación en sí la mayor parte del tiempo🤷 y probablemente no sea tan emocionante, pero no menos importante ☝️

En producción, generalmente necesitamos ocuparnos de las siguientes cosas:

  • Analytics
    Todo tipo de eventos de seguimiento diferentes, etc. Cosas como Google Analytics , Segmento , HotJar , etc.
  • Supervisión del estado
    Esto incluye cosas, como comprobaciones de estado, que se pueden incluso las pruebas se ejecutan en producción, informes de errores (como Sentry ), etc.
  • Rendimiento
    Es algo similar al elemento anterior, pero más orientado al rendimiento. Esto incluye medir el tiempo de respuesta, la primera pintura significativa, etc. (probablemente la herramienta n. ° 1 – Lighthouse )
  • Pruebas A / B
    Todo tipo de soluciones de pruebas A / B o indicadores de funciones.
  • Almacenamiento en caché
    Herramientas como Barniz , Cloudflare .

Todas ellas se pueden unificar en sus aplicaciones de front-end en la empresa, lo que simplificará la vida de sus ingenieros . Por ejemplo, agregando paquetes con las configuraciones iniciales predefinidas y agregando esos paquetes a su proyecto de arranque.

Otra parte de la producción es la preparación del código, como:

  • Minificación
    Solo minificación de código 😄
  • Mapeo de origen
    Es posible que también se necesiten mapas de origen para algunas otras herramientas, como Sentry.
  • Preparación de activos
    Preparación para pantallas con diferentes resoluciones, imágenes recortadas, etc.

Son excelentes candidatos para ser agregados a el conjunto de herramientas que tenemos para administrar aplicaciones front-end, del que estábamos hablando en la sección Herramientas.

Producción

Resumen:

Idealmente, todos esos deberían ser agregado a cada proyecto de interfaz de forma predeterminada en la fase de arranque. Y los ingenieros solo se ocuparían de agregar las claves API correctas en los lugares correctos para las herramientas.

6. Desarrollo

Herramienta CLI

Ya hablamos parcialmente de la experiencia de desarrollo en la sección Herramientas, cuando tocamos la herramienta CLI frontend. Las herramientas unificadas son una gran parte de los ingenieros «a diario, pero no todo.

API

Una API cómoda para trabajar localmente es la segunda cosa increíble que podemos hacer para mejorar el desarrollador. la experiencia y la velocidad de desarrollo. Por lo general, proporcionar API localmente para los ingenieros de front-end no es un proceso trivial: esto puede incluir la instalación de herramientas o marcos con los que pueden no estar familiarizados. Incluso si la configuración está acoplada, esto puede requerir una gran cantidad de recursos de las máquinas del desarrollador (si no lo es, esto se puede considerar como una configuración). ¿Cuál puede ser una solución en este caso? API servida externamente. Puede ser un servidor único para todos los ingenieros o algún mecanismo para iniciar fácilmente su propio servidor dedicado para el desarrollo.

CI

CI es la tercera parte importante. Supongo que su empresa ya ha elegido alguna herramienta de CI para el frontend y utiliza esta única herramienta (p. ej., Circle CI ,

Concourse CI , o cualquier otro). De lo contrario, debería unificar eso.

La configuración de CI del proyecto en particular, en mi opinión, debería ser parte del trabajo del equipo, que está trabajando en el proyecto. Esto le da la oportunidad a CI de ser estable porque hay personas que están interesadas en que CI trabaje, lo use todos los días y tenga el poder y las habilidades para arreglarlo, configurarlo y mejorarlo.

Sin embargo, no todo el trabajo debe ser realizado por el equipo. Para las aplicaciones de front-end, existe una serie de trabajos bastante específicos, que potencialmente pueden ser necesarios. Especialmente, si pudiéramos unificar la estructura de carpetas / código, pila tecnológica, etc. Entonces, después de un tiempo en su empresa, podría llegar el momento en que pueda detectar esos patrones para las etapas de su herramienta de CI, implemente esas etapas como algún tipo de «bloques de construcción» y brinde una oportunidad para que sus ingenieros simplemente construyan sus tuberías de CI a partir de esos «bloques de construcción» unificados.

Entornos de demostración

Y finalmente la última: verificación de la característica implementada.Una vez que los ingenieros tienen todo hecho e implementado, casi siempre necesitan de alguna manera verificar cómo se ve y cómo funciona y compartir esto con otros ingenieros, diseñadores u otras partes interesadas. Para tales necesidades, funciona muy bien la versión implementada temporalmente de su aplicación para el RP específico con la URL proporcionada.

Aplicación temporalmente implementado
Aplicación implementada temporalmente

Esta solución acelera la comunicación entre diferentes equipos y personas y creo que esto es solo un debe tener. Sin embargo, esta versión implementada temporalmente debe estar lo más cerca posible de la producción, porque también puede ser una gran herramienta para verificar algunos errores o errores superficiales.

Esto se puede agregar fácilmente a sus proyectos y automatizar si su interfaz las canalizaciones del proceso de construcción e implementación de aplicaciones están unificadas. Además, herramientas de este tipo o similares como Kubernetes y Helm pueden ayudar mucho en la implementación.

Desarrollo

Resumen:

Flujos de desarrollo cómodos y eficientes con una sola herramienta de CI con componentes básicos para realizar cualquier Canalización de CI, con herramientas de interfaz CLI unificadas y entornos de demostración. Todo esto debería hacer que nuestro proceso de desarrollo sea lo más fluido posible. Multiplique esto por el número de ingenieros que tiene en la empresa y comprenderá lo beneficioso que es.

7. Modularidad

Este tema es muy extenso y podría requerir un artículo aparte para hablar, pero trataría de repasarlo brevemente.

En organizaciones grandes, las bases de código enormes no son raras cosa. Con todos los problemas conocidos que vienen junto con ellos, como pipelines CI lentos, problemas con el trabajo colaborativo, pruebas lentas, etc. Entonces, la gran parte de la arquitectura frontend es una decisión sobre cuán granulares queremos ver las aplicaciones / módulos frontend independientes.

Hay 3 modelos principales que tenemos ahora:

  • Monolith
    Un gran repositorio con un solo proyecto y todo el código allí, todos los equipos están trabajando juntos en este repositorio al mismo tiempo.
  • Monorepo
    Muchos proyectos, pero aún un gran repositorio ( monorepo en la wiki ). Todos los equipos siguen trabajando en el mismo repositorio, pero con diferentes proyectos. Ya existen oportunidades para solucionar algunos problemas, que tenemos con un enfoque monolítico, ejecutando pipelines solo para proyectos específicos, los proyectos tienen conjuntos de pruebas más pequeños, etc. Herramientas como Lerna puede hacer su vida mucho más fácil en caso de que elija este enfoque.
  • Repo por proyecto
    Cada proyecto tiene su propio repositorio y todas las cosas de apoyo, como pipelines de CI, implementaciones, etc.

En todos esos modelos, el proyecto puede significar una aplicación de interfaz independiente, una página, módulo de interfaz independiente, etc. Esto depende de qué tan granular desee decidir dividir sus aplicaciones de interfaz. En la mayoría de los casos, esta división debe estar sincronizada con la estructura de organización deseada y la gestión de personas.

El segundo gran tema después de decidir cómo dividir su aplicación será cómo conectar esas piezas (si lo decidió para dividir su aplicación).

Y aquí tenemos los siguientes enfoques:

  • Composición en tiempo de construcción
    Sus proyectos pueden ser solo paquetes npm, instalados y compuestos durante el tiempo de compilación.
  • Server- composición del lado
    Este enfoque generalmente incluye la representación del lado del servidor y la composición que ocurre en un servidor. Herramientas como Hypernova pueden ayudar a organizarlo mejor.
  • Composición del lado del cliente
    Composición de los proyectos dentro del navegador. En el blog de Martin Fowler, hay una explicación bastante buena de algunos enfoques: aquí . Además, es muy importante mencionar Module Federation , un nuevo enfoque introducido en Webpack 5 .
  • Composición de la ruta
    Súper simple: solo cada proyecto tiene su propia URL y en un «nivel Nginx» decidimos dónde redirigir a los usuarios.(lo siento, por esa explicación 😄 pero pensé que sería la más fácil de entender)

Como dije antes, es muy difícil cubrir este tema en un formato tan pequeño, pero espero que al menos haya encontrado algunas ideas interesantes para usted y que profundice en los temas por sí mismo 🙏🏻 .

Modularidad

Resumen:

Encontramos una manera de hacer felices y productivos a nuestros equipos organizando los repositorios, dividiendo nuestros proyectos en partes más pequeñas (lo más probable), al hacer que los equipos sean más independientes entre sí.

Bienvenido al paraíso 😁

8. Pruebas

Hay tantos recursos disponibles sobre pruebas para aplicaciones de front-end, por lo que trataría de no entrar en detalles, lo cual puedes easi encontrar, pero centrarse más en los problemas de las grandes organizaciones y cómo podemos resolverlos.

El primero de ellos: cada ingeniero entiende las técnicas de prueba de manera diferente, también qué técnica aplicar en qué situación, cómo escribir » buenas ”pruebas, etc. Por lo tanto, tiene mucho sentido documentar con bastante precisión todos los matices y pautas de los niveles de prueba utilizados en la empresa y las pautas para cada uno de ellos.

Los posibles niveles de prueba que desea tener en su estrategia de prueba:

  • Pruebas unitarias
  • Pruebas de integración
  • Pruebas E2E
  • … y otras

Además, como segundo paso, debemos unificarlas en diferentes aplicaciones frontend de la empresa, para que la gente no tenga preguntas sobre cómo y qué probar cuando se cambia a un proyecto diferente.

Si logró unificar los niveles y enfoques de prueba, automáticamente puede ayudar a resolver el segundo problema: la configuración de la infraestructura de prueba. Cada proyecto por sí solo necesita instalarlo y configurarlo localmente y en CI alguna infraestructura de prueba. Por ejemplo, decidimos que usamos Cypress y debe ejecutarse dentro de una imagen acoplable. Esto necesita algo de tiempo para configurarse localmente y en CI. Si multiplicamos eso por la cantidad de proyectos que tenemos, es una enorme cantidad de tiempo. Entonces, la solución: unificar eso nuevamente y proporcionar algunas herramientas para los proyectos. Suena fácil, pero su implementación requiere una gran cantidad de tiempo.

Pruebas no relacionadas con el tiempo de desarrollo

También quería tocar otra forma de probar sus aplicaciones después de las características ya implementadas y desplegadas. Y sí, la supervisión, por supuesto, es parte de ella 😁.

Ya mencionamos en secciones anteriores el monitoreo de errores y rendimiento para aplicaciones frontend, monitoreo del tiempo de actividad, la respuesta desde diferentes ubicaciones.

También es genial tener Las pruebas Lighthouse se ejecutan en su sitio web (se pueden incluir en las canalizaciones de CI). Para encontrar cuellos de botella de rendimiento, problemas de accesibilidad y mejorar la calidad de las páginas web en general.

Y el Último: pruebas de producción de los flujos comerciales más importantes. Lo más probable es que funcionen mejor si las ejecuta directamente en el producto. en el entorno, pero también puede ser posible una modificación cuando podemos ejecutar tales pruebas en un entorno de prueba / ensayo, que está muy cerca del de producción o incluso lo refleja. Hay un artículo muy bueno sobre este tema – (aquí).

Pruebas

Resumen:

Tenemos pautas de prueba claras con niveles de prueba necesarios definidos para cada aplicación de interfaz. Tenemos una única canalización de CI para cada aplicación y tenemos una sola herramienta CLI, que ayuda a ejecutar pruebas localmente.

Palabra final

Realmente espero que hayan encontrado algo interesante en esto. artículo. Lamento mucho que en la mayoría de los temas acabo de tocar la superficie de los problemas. Y estará encantado de discutirlos más, así que deje sus preguntas en los comentarios o envíeme un ping directamente en Twitter: @denieler .