Video Summary and Transcription
Esta charla explora los beneficios de usar TuberApple, una herramienta para potenciar la experiencia de desarrollo. Destaca las ventajas de los monorepos, como la reutilización de código, los estándares compartidos, la mejora de la colaboración en equipo y los cambios atómicos. TuberApple, específicamente Tuburepo, ofrece una ejecución de tareas eficiente a través de la caché y la programación optimizada. Simplifica el desarrollo de monorepo permitiendo la ejecución paralela de tareas y la coordinación sin fisuras de los cambios. Tubo, otra herramienta dentro de TuberApple, permite la ejecución inteligente de tareas, la declaración de dependencias de tareas y el almacenamiento en caché eficiente en monorepos.
1. Introducción a TuberApple
Hola a todos. Gracias por acompañarme hoy. Vamos a hablar de cómo potenciar tu experiencia de desarrollo con TuberApple. Un poco sobre mí. Mi nombre es Bruno Paulino. Soy líder técnico en Any26, una empresa que construye una plataforma para que los ingenieros construyan aplicaciones web y bibliotecas. Discutiremos sobre monorepo, multirepos y cómo las empresas organizan su código.
Hola a todos. Gracias por acompañarme hoy. Vamos a hablar de cómo potenciar tu experiencia de desarrollo con TuberApple. Un poco sobre mí. Mi nombre es Bruno Paulino. Soy líder técnico en esta genial empresa llamada Any26. Estamos construyendo el banco que nos encanta usar. Y soy un ingeniero de software centrado en la web. Y allí, en Any26, estamos construyendo la plataforma para que todos los ingenieros construyan aplicaciones web en ella. No solo aplicaciones web, sino también bibliotecas web. Podrías pensar en componentes del sistema de design, por ejemplo. Y allí, no me gusta llamarnos DevOps. Realmente nos gusta llamarnos DevOps. Así que realmente ayudamos a los ingenieros web a enviar estos lo más rápido posible al navegador. También soy bpaulino0 en Twitter. Así que si usas Twitter y quieres seguirme, por favor hazlo. Estoy allí. Así que vamos a entrar en materia. Esta presentación está dividida en dos partes. En la primera, vamos a hablar sobre monorepo, multirepos y cómo puedes usarlos. Y en la segunda parte, vamos a hablar realmente sobre tuberepo. Y luego para cerrar, vamos a ver una agradable demostración en vivo. Pero antes de empezar, quiero hablar sobre multirepos, monorepos y cómo las empresas realmente organizan su code. El enfoque más común es tener multirepos, ¿verdad? Vas a una empresa y luego tienen varios proyectos diferentes y organizan los proyectos en diferentes repositorios. Esa es la forma más sensata de hacerlo. Tienes varios equipos diferentes trabajando en diferentes proyectos. Tienen sus propias herramientas, tienen sus propios standards y así sucesivamente, y eso es bastante común y muy razonable, ¿verdad? Quieres dar a los equipos la independencia de usar sus propias herramientas, sus propias formas de construir software y enviarlo lo más rápido posible. Pero hay otra forma, ¿verdad? Hay una forma de organizar tu
2. Beneficios de los Monorepos
Aún puedes tener un monorepo y puedes tener microservicios, por ejemplo, dentro del monorepo. La primera razón es la reutilización de código, facilitando compartir código con compañeros de equipo. La segunda razón son los estándares compartidos, permitiendo una configuración y adopción consistentes en todos los proyectos. La colaboración en equipo también mejora, ya que los ingenieros pueden compartir fácilmente pull requests y trabajar juntos sin configuración adicional. Finalmente, se pueden hacer cambios atómicos, asegurando que todas las aplicaciones y paquetes funcionen juntos sin problemas.
code en el mismo repositorio. Existen los monorepos. No confundas los monorepos con los monolitos. Así que aún puedes tener un monorepo y puedes tener microservices, por ejemplo, dentro del monorepo. La única diferencia de un monorepo a un enfoque multirepo es realmente que tienes todas tus aplicaciones o paquetes, bibliotecas dentro del mismo repositorio. Pero entonces tú podrías preguntarte, ¿por qué necesito tener un monorepo? ¿Por qué necesito poner todo mi code junto en el mismo repositorio en lugar de tenerlos separados en repositorios individuales? Debe haber una buena razón para que otras empresas hagan eso, ¿verdad? Como por qué los monorepos son tan populares en esas empresas, por ejemplo, Google, Netflix, Facebook y Twitter, todos ellos usan monorepos de alguna forma u otra. Y debe haber muy buenas razones para que ellos no opten por el enfoque multirepo, ¿verdad? Y hablemos de ellas. Así que la primera es realmente la reutilización de code. Si tienes todo en el mismo repositorio, entonces es mucho más fácil para ti compartir code con tus compañeros de equipo. Piénsalo, podrías tener un paquete de modules donde tienes todos tus database modules, y también puedes tener un paquete allí con tus componentes de UI. Y entonces todos los demás en tu equipo pueden simplemente reutilizarlos sin tener que reinventar nada o reimportar nada o instalar ningún paquete extra.
Otra razón por la que podrías querer considerar un monorepo es tener standards compartidos. En un monorepo, puedes tener verdaderos standards compartidos en toda tu base de code. Porque piensa en ello, podrías tener una configuración de yeslin que se comparte completamente en todos los paquetes, y luego puedes actualizarla en un solo lugar. Y entonces todos los demás paquetes pueden beneficiarse de ello inmediatamente. Así que si estás usando TypeScript, por ejemplo, puedes tener una sola configuración de TypeScript compartida en todos tus proyectos. Así que también fue muy fácil adoptar y compartir cosas entre los paquetes dentro del monorepo. Volviendo al ejemplo que di antes, también puedes tener un modelo de database compartido con consultas allí y luego puedes simplemente reutilizarlo en toda tu configuración de monorepo, donde necesites acceso a la database, por ejemplo. Otra cosa que funciona muy bien en la configuración del monorepo es la colaboración en equipo. Así que si tienes todo en el mismo repositorio, puedes compartir fácilmente un pull request con otros ingenieros y obtener feedback porque ellos ya tienen todo el contexto alrededor de la base de code. No tienen que configurar nada. No tienen que instalar una versión diferente de node. No tienen que configurar ningún SDK en la máquina o algo así porque han estado trabajando en la misma base de code. Ya tienen todas las herramientas instaladas. Así que no tienen que averiguar nada. Si necesitas hacer una sesión de programación en pareja, por ejemplo, es mucho más fácil hacerlo. Puedes simplemente compartir una pantalla, iniciar el servidor de desarrollo, y entonces todo está allí. No necesitas clonar nada. No necesitas hacer ninguna configuración. Es mucho más fácil y rápido para un equipo grande.
Otro gran punto de venta para el monorepo son los cambios atómicos. Pero, ¿qué quiero decir con eso? Así que si tienes un solo repositorio, puedes cambiar varias aplicaciones y paquetes diferentes al mismo tiempo, en el mismo pull request.
3. Ejecución eficiente de tareas con Tuburepo
En un monorepo, todo puede estar en las mismas solicitudes de pull, asegurando que los cambios estén coordinados y probados juntos. El aislamiento del código se logra a través de los espacios de trabajo, que permiten paquetes autónomos con dependencias explícitas. Tuburepo, un sistema de construcción específicamente para JavaScript y TypeScript, proporciona una ejecución eficiente de tareas al almacenar en caché las ejecuciones anteriores.
De esta manera, puedes garantizar que todo va a funcionar en conjunto. En contraste, si tienes múltiples repositorios, entonces tienes que asegurarte de que puedes coordinar esos cambios con diferentes equipos. Y luego te aseguras de que lanzas esta versión diferente de la biblioteca o la aplicación para que puedas avanzar con un cambio diferente. En el monorepo, todo podría estar junto en las mismas solicitudes de pull. Si tienes pruebas, si tienes pipelines de construcción, todo en tu sistema de CI, puedes garantizar que todo va a funcionar, o no fusionas ese cambio. Por lo tanto, es más sencillo mantener todo sincronizado.
Por último, pero no menos importante, otro punto importante es el aislamiento. Podrías preguntarte, ¿cómo puedes tener aislamiento de code en un monorepo, donde todo está dentro del mismo repositorio? Esto es posible gracias a los espacios de trabajo. Hoy en día, npm, pnpm y YARN implementan espacios de trabajo, que es una forma de tener paquetes autónomos. Así que todos tus paquetes, incluyendo bibliotecas y aplicaciones, son completamente autónomos con sus propias dependencias declaradas e instaladas por separado. Y las dependencias están todas explícitamente definidas en cada paquete. Así que puedes asegurarte de que esos paquetes, tienen todas las dependencias que necesitan para ser construidos, probados y enviados a producción de manera adecuada.
Muy bien. Ahora vemos que tenemos el packaging resuelto, ¿verdad? Parece que podemos tener un monorepo sólido gracias a los espacios de trabajo. Esta es una característica muy ordenada. Funciona muy bien en todos los sistemas comunes de packaging que tenemos ahora, incluyendo npm, pnpm y YARN. Pero ejecutar tareas de manera eficiente, es bastante complicado. Todavía no es muy eficiente. Puede ser muy desafiante o al menos lo era hasta ahora. Hoy tenemos Tuburepo, que es un sistema de construcción que fue creado específicamente para el JavaScript y el TypeScript ecosystem. Tuburepo fue construido por Jared Palmer. Es un ingeniero muy prolífico y está desarrollando Tuburepo como una herramienta de código abierto. Hoy en día, Tuburepo es parte de VSL y todavía se está construyendo en código abierto. Así que vamos a echar un vistazo a las características que nos proporciona Tuburepo para que podamos construir este monorepo de una manera muy eficiente. La primera es que Tuburepo nunca hace el mismo trabajo dos veces. Así que si ejecutas una construcción o una prueba o una tarea de LinkedIn, Tuburepo va a recordar eso y lo va a almacenar en caché para ti. Si quieres hacerlo de nuevo para un paquete diferente que no cambió, Tuburepo simplemente dirá, hey, ya has hecho esta tarea. No tienes que ejecutarla de nuevo. Te mostraré los registros aquí de la ejecución anterior. Y entonces todo funcionaba de la misma manera.
4. Ejecución Mejorada de Tareas con Tuburepo
Tuburepo proporciona programación y almacenamiento en caché optimizados, permitiendo una ejecución eficiente de tareas. Ejecuta tareas en paralelo, maneja dependencias y comparte la caché entre equipos y sistemas CI. Tuburepo no tiene sobrecarga en tiempo de ejecución. En nuestra demostración en vivo, exploraremos un repositorio de demostración utilizando Tuburepo como base.
Lo verás en nuestra demostración en vivo al final. Otra cosa que es una gran ventaja al usar Tuburepo, es la programación optimizada. Tuburepo averiguará cuántos CPUs tienes disponibles en tu computadora y luego va a ejecutar tantas tareas en paralelo como puedas. Así que si tienes tareas que son completamente independientes y pueden ejecutarse en paralelo, Tuburepo se asegurará de que realmente pueda ejecutarse en diferentes núcleos de CPU, por ejemplo. Si esas tareas, en realidad tienen dependencias. Así que, por ejemplo, si tu tarea de prueba depende de una tarea de construcción, Tuburepo se asegurará de que la tarea de construcción se ejecute primero y luego la tarea de prueba seguirá a eso. También vamos a ver eso en la demostración en vivo al final. ¿Recuerdas que te dije que Tuburepo nunca hará el mismo trabajo dos veces? Aquí, Tuburepo lleva esto al siguiente nivel. Así que si haces algo en tu máquina, puedes compartir esta caché en todo tu equipo de desarrollo y también en tus servidores CI. Así que, por ejemplo, si ejecutas una prueba o una tarea de lean localmente en tu máquina y si tienes tu caché configurada, puedes subir esta caché automáticamente, Tuburepo hace eso por ti, y luego va a ser compartida entre todos tus sistemas CI y también entre todos tu equipo de desarrollo, y luego ellos también se beneficiarán de esta caché automáticamente. Esta característica funciona de manera transparente, pero tienes que usar VCEL conectado a tu máquina y servidores CI, o tienes que alojar tu propia caché remota. Hay algunas cachés remotas que son open-source y puedes implementarlas en tu propia cloud.
5. Explorando el Repositorio de Demostración
Tuburepo no tiene sobrecarga en tiempo de ejecución y es solo una dependencia de desarrollo, no afecta tu código en producción. En nuestra demostración en vivo, exploraremos un monorepo utilizando Tuburepo como base. Recorreremos el monorepo, destacando el archivo package.json con tareas y dependencias específicas del monorepo, la carpeta de paquetes que contiene paquetes compartidos, y la carpeta de aplicaciones con aplicaciones separadas para diferentes propósitos.
También veremos eso en acción en nuestra demostración en vivo muy pronto. Por último, pero no menos importante, Tuburepo no tiene sobrecarga en tiempo de ejecución, lo que significa que Tuburepo es solo una dependencia de desarrollo. No envía nada a tu code cuando va a producción. De hecho, todos tus paquetes, ni siquiera saben que Tuburepo existe, porque Tuburepo solo existe a nivel del monorepo, y todos tus paquetes son completamente independientes y desconocen por completo a Tuburepo en tu paquete.
Así que basta de hablar. Vamos directo a nuestra demostración en vivo. Aquí tenemos el enlace para nuestro repositorio. No tienes que code a lo largo, solo sígueme en la pantalla. Pero al final, si quieres darle un inicio al repositorio, siéntete libre.
Bien, así que estamos aquí en nuestro VS code, y tengo aquí un repositorio de demostración que preparé para esta charla. Aquí tenemos un monorepo utilizando Tuburepo como base. En este monorepo, estoy usando pnpm para administrar los paquetes, pero también podrías usar yarn o npm de la misma manera. Así que echemos un vistazo, hagamos un pequeño recorrido por el monorepo y entendamos cómo podemos componer esos paquetes.
Aquí, a nivel raíz, tenemos un archivo package.json. Justo el mismo archivo package.json que estás acostumbrado a ver en todos los proyectos de JavaScript o TypeScript. La única diferencia aquí es que en un monorepo, en realidad tienes tareas y dependencias declaradas aquí que están destinadas solo para el monorepo. Vale, vamos a echar un vistazo a las tareas específicas más adelante. Aquí tengo una carpeta de paquetes con un montón de todos los paquetes. Así que tenemos como una colección de paquetes aquí. El primero es yes-lint-config, es básicamente como este yes-lint-config común que puedo compartir en todos mis paquetes en nuestro monorepo. Luego tenemos un ts-config, es básicamente nuestra configuración de TypeScript que también se comparte en paquetes y aplicaciones. Luego tenemos una biblioteca de UI, es básicamente nuestro sistema de design, digamos. Es una biblioteca muy pequeña solo para esta demostración, pero verás eso en acción muy pronto. Y luego encima de eso, tenemos la carpeta de aplicaciones. Y ahí es donde segregamos nuestras aplicaciones de una manera separada. Así que tenemos aplicaciones y paquetes, eso está más destinado a bibliotecas, y luego aplicaciones, puedes construir una imagen de docker, por ejemplo, puedes desplegar en un entorno serverless y así sucesivamente. No importa realmente. En este caso, tenemos dos aplicaciones. Tenemos la aplicación Shop, que es nuestra aplicación Next JS, donde los clientes van a comprar camisetas. Y luego tenemos nuestra aplicación de administración.
6. Uso de TurboRepo para el Desarrollo de Monorepos
TurboRepo ayuda con el desarrollo de Monorepos al ejecutar tareas en paralelo. La tarea dev en el archivo package.json ejecuta Turbo en paralelo para todos los paquetes dev. La consola muestra diferentes salidas para admin dev, shop dev y UI dev. Se puede acceder a la aplicación de tienda y administración en el navegador, con la aplicación de administración sirviendo como back office para los empleados. Una característica común entre estas aplicaciones es el botón azul, probablemente de la biblioteca de componentes del sistema de diseño.
Es algo así como el back office. Entonces los empleados pueden reembolsar pedidos, enviar cosas al cliente, y así sucesivamente. Así que veamos cómo TurboRepo puede realmente ayudarnos con el desarrollo en nuestro Monorepo.
Voy a abrir mi terminal aquí. Y luego voy a ejecutar pnpm dev. Esto va a encender nuestro servidor de desarrollo en nuestro Monorepo. Y aquí es donde Turbo ya nos está ayudando a ejecutar tareas en paralelo tanto como sea posible. ¿Recuerdas que te dije que puedes declarar tareas y luego Turbo puede encargarse de ejecutarlas en paralelo? Eso es lo que está sucediendo aquí en mi archivo package.json en el nivel raíz del Monorepo. Tengo una tarea dev aquí que está usando Turbo. Es nuestra dependencia aquí que está declarada abajo como una dependencia de desarrollo. Estoy usando la última versión de Turbo Repo y tenemos Turbo aquí llamando a Turbo run dev dash dash parallel, lo que significa que, oye, simplemente ejecuta todas las tareas que tenemos en nuestros paquetes llamados dev en paralelo y no te preocupes por sus dependencias entre sí. Así que simplemente ejecútalas en paralelo. Y eso es lo que Turbo está haciendo aquí.
Si miras la consola, podemos ver que tenemos un montón de diferentes salidas aquí incluso con diferentes colores. Así que tenemos el admin dev, tenemos el shop dev, y tenemos el UI dev. Así que esto está ejecutando el comando dev para todos esos paquetes. Así que vamos a un navegador y luego veamos cómo se ven nuestra tienda y la aplicación de administración. Así que voy a ir a localhost 3000 y eso debería ser nuestra tienda. Así que como puedes ver aquí, tenemos la Turbo tienda y puedo agregar cosas al carrito. Es solo una tienda ficticia. No hace mucho, pero puedes ver aquí que hay un pequeño botón aquí. Y luego voy a ir a localhost 2001, 3001 y ahí es donde tenemos el Turbo admin y eso es algo así como nuestro back office de administración para los empleados. Y aquí puedes reembolsar pedidos. Eso también es solo una aplicación de maqueta para mostrarte. Pero observa que una cosa común entre esas aplicaciones es este botón azul aquí. Correcto. Es bastante azul. Y son muy similares. Así que probablemente esto viene de nuestro sistema de diseño biblioteca de componentes. Echemos un vistazo.
7. Desarrollo y Pruebas en un Monorepo
En VS Code, podemos hacer cambios fácilmente en la biblioteca de UI que se reflejan tanto en las aplicaciones de administración como en la tienda. El desarrollo en un monorepo con TurboRepo simplifica el proceso en comparación con los repositorios separados. También podemos ejecutar pruebas y tareas de lint en todos los paquetes.
Vamos a VS Code de nuevo. Y luego echemos un vistazo a los paquetes, UI y luego tenemos aquí SRC button. Así que tenemos un botón de React muy simple aquí. No hace mucho, pero tenemos algo de CSS aquí. Cambiemos esto un poco. Así que cambiémoslo a algún tono de negro. Y luego volvamos a Firefox. Podemos ver que se refleja inmediatamente. Correcto. Así que nuestro entorno de desarrollo está recogiendo cambios entre paquetes. Observa que no hice ningún cambio en mi aplicación de administración. De hecho, cambié mi biblioteca de UI. Y ya podemos ver eso reflejado aquí. Así que ya está funcionando de la misma manera. Y luego, si voy a mi tienda, también vemos que el botón, también está en un tono de negro aquí. Y eso es bastante genial. Así que puedes hacer el desarrollo localmente sin tener que configurar nada extra. Imagina que tienes tu biblioteca de UI en un repositorio diferente, e imagina que estás usándolo también en tu aplicación de administración y en tu aplicación de tienda. Eso es simplemente mucho más difícil para ti hacer el desarrollo, ¿verdad? Tendrías que lanzar una nueva versión de la biblioteca y luego importar esta nueva versión de la biblioteca en tu aplicación y así sucesivamente. Así que se complica un poco más el desarrollo. En un monorepo, incluyendo turbo repo, entonces las cosas son mucho más simples de hacer.
Ahora volvamos a VS Code. Ya que hicimos algunos cambios aquí, veamos cómo podemos ejecutar pruebas y lint aquí. Voy a detener mi servidor de desarrollo. Y luego voy a hacer una tarea de lint aquí. Voy a ejecutar pmp y lint. Y luego veamos qué pasa. Ejecutó una tarea de lint. Y vemos aquí un montón de otras sugerencias. Así que nuestro lint aquí está configurado para ejecutarse en todos nuestros paquetes.
8. Ejecución Inteligente de Tareas en Monorepo
Tubo determina inteligentemente qué tareas de lint ejecutar basándose en la caché. Solo ejecuta las tareas necesarias, lo que resulta en un desarrollo eficiente de monorepo. Al ejecutar el comando de prueba PNPM, se proporcionan los resultados de las pruebas y la salida sin ejecutar explícitamente una compilación.
Así que tenemos aquí UI lint, tenemos aquí shop lint y tenemos aquí admin lint. Pero fíjate aquí abajo que vemos una salida que dice tres exitosos y dos de ellos fueron almacenados en caché y tres en total. Lo que significa que dos de ellos ya se han ejecutado en el pasado. Así que Tubo ya sabe que, oh, solo un paquete cambió, que fue solo el paquete UI. Y si miras de cerca aquí, podemos ver que el lint de UI aquí es un fallo de caché. Así que Tubo sabe, hey, no tenemos una caché para estos hashes aquí. Tubo tiene un algoritmo de hashing muy inteligente detrás de escena que simplemente está calculando qué archivos han cambiado y luego sabe dónde necesita ejecutar esa tarea. Así que en este caso, es un fallo de caché. Así que va a ejecutar el lint para este paquete. Para los otros paquetes, tenemos aquí shop lint. Es un acierto de caché. Observa que Tubo encontró esto ya en la caché. Así que no va a ejecutar esto. Para el otro paquete, admin lint, también es un acierto de caché. Así que ya se ha ejecutado antes. Porque lo ejecuté antes de mostrarte aquí en la demo y luego ya está en caché. Y eso es bastante genial. Correcto. Así que ahora tu monorepo solo está ejecutando lo que realmente es necesario.
Así que ahora voy a ejecutar otro comando aquí. Pruebas de PNPM. Así que vamos a probar nuestros paquetes. Veamos cómo se comporta. Ejecuto la tarea de prueba. Y luego tenemos un montón de salida aquí. Así que echemos un vistazo. Ahora tenemos una salida diferente aquí. Tenemos las pruebas de UI y la compilación de UI. No le dije a Tubo o PNPM que ejecutara una compilación. Correcto.
9. Declarando Dependencias de Tareas en Tubo
Aprenda cómo declarar dependencias entre tareas en Tubo usando Tubo.json. La tubería en el archivo Tubo.json le permite especificar el orden de ejecución de las tareas y sus dependencias. Al usar la clave 'depende de', puede asegurarse de que las tareas se ejecuten en el orden correcto. También se pueden especificar las salidas para definir la salida esperada de cada tarea.
Solo le dije que ejecutara una prueba. Pero recuerde que le dije que en realidad puede declarar dependencias entre tareas. En este caso, mi tarea de prueba, en realidad depende de una tarea de construcción. Así que se asegura de que la construcción se ejecute primero. Entonces, veamos cómo puedes lograr eso con Tubo.
Entonces, una vez que tienes Tubo instalado en tu repositorio, lo único que necesitas es un archivo Tubo.json. Es este archivo aquí en la raíz de tu monorepo y ese es el archivo donde declaras todo relacionado con Tubo repo. Y lo más importante que tienes allí es esta tubería aquí. La tubería es donde declaras tu tubería de tareas. Y ahí es donde tienes que ser muy explícito en qué tareas quieres ejecutar con Tubo y cómo van a ser sus dependencias.
Entonces, por ejemplo, tenemos la tarea de construcción aquí y luego tenemos una clave llamada depende de. Depende de básicamente le dice a Tubo, oye, antes de ejecutar la tarea de construcción, asegúrate de que hayas ejecutado cualquier otra cosa que dependa de ella. Así que en este caso es caret build, lo que significa que, oye, ejecuta cualquier tarea de construcción de cualquier dependencia de la que dependo antes de ejecutar mi construcción. Entonces, por ejemplo, si la aplicación de administración depende de la biblioteca UI, va a construir la biblioteca UI primero y luego va a ser la aplicación siguiente. Así que para asegurarme de que la biblioteca UI estará lista antes de que pueda construir la aplicación. Las salidas aquí declaran lo que esperamos que sea una salida para esta tarea. Entonces, si estoy haciendo una construcción en el proyecto Next, en realidad puedo tener varias carpetas de salida, ¿verdad? Next genera varias carpetas diferentes. En este caso, quiero poder almacenar en caché esta carpeta y la carpeta .next, lo que significa que en realidad puedes recuperar esos artefactos de la caché una vez que los necesites. La tarea de prueba, no es diferente. Sigue el mismo estándar. Tiene depende de y luego dice caret build, lo mismo que teníamos para construir, pero también depende de construir de nuevo. Entonces, lo que significa que cada vez que ejecutes una tarea de prueba para cualquier paquete, asegúrate de que ejecutes una construcción primero para cualquier paquete del que dependa. Volvamos a nuestro ejemplo para la aplicación. Entonces, tenemos la aplicación de tienda que depende de la biblioteca UI. Si quiero probar la aplicación de la tienda, quiero asegurarme de que la biblioteca UI esté lista y disponible para mí. Entonces, voy a ejecutar la construcción primero y luego voy a ejecutar la prueba. Y eso también es cierto para la biblioteca misma. Va a construir la biblioteca misma y luego va a ejecutar. Aquí las salidas significan que se espera que esta tarea produzca algo. Correcto.
10. Dependencias de Tareas y Caché en Tubo
La tarea de prueba no genera nada y solo almacena en caché los registros. La tarea de enlace no genera nada y puede ejecutarse en paralelo. El comando dev no tiene dependencias, salidas ni almacenamiento en caché.
En este caso, es un array vacío. No genera nada. Así que básicamente la tarea de prueba no tiene que, no tiene que almacenar nada en caché además de los registros que genera.
Luego tenemos la tarea de enlace, que no tiene un depende de, solo tiene las salidas Y aquí declara un array vacío de nuevo, lo que significa que no genera nada. No depende de nadie. Observa que no tenemos la clave depende de aquí, lo que significa que puedes ejecutar lint en paralelo tanto como sea posible.
Luego tenemos el comando dev. El comando dev aquí tampoco tiene ninguna dependencia y tampoco genera nada. Solo tiene un caché falso, lo que significa que Tubo nunca almacena nada para Dev, lo que significa que siempre que estés desarrollando localmente, siempre querrás tener la salida fresca. Está bien. Pero ahora que tenemos esas tuberías declaradas, ¿cómo sabe Tubo que necesita ejecutar esas tareas.
11. Ejecución de Tareas en Tubo
Ejecutamos múltiples tareas en todo el monorepo utilizando el binario tubo. En CI, Tubo ejecuta tareas en paralelo, considerando las dependencias.
Luego volvemos de nuevo a nuestro archivo package.json. ¿Recuerdas que te mostré el comando dev? Es lo mismo para build, lint, test y CI. Vamos a ejecutar todos ellos. Ya hemos ejecutado lint y test, y luego vamos a ejecutar el CI en nuestro entorno CI, y te voy a mostrar cómo se muestran allí. Así que cada vez que quieras ejecutar una tarea en tu monorepo, simplemente las ejecutas llamando al binario tubo. Así que se llama simplemente tubo. Y luego pasas el comando run, y luego le dices a TuboNet la tarea que necesita ejecutar. En este caso, es test. Así que hace solo una tarea específica para todos los paquetes en tu monorepo. En nuestro CI, es un poco diferente. Le estoy diciendo a Tubo que ejecute lint y test. Así que va a ejecutar todas esas tareas en paralelo tanto como sea posible. Si tienen alguna dependencia, entonces ejecutarán esas dependencias de tareas antes de que puedan ser ejecutadas en paralelo también.
12. Caché y Comportamiento de CI
Tubo almacena en caché las tareas ejecutadas y reproduce los registros. Tubo sabe qué tareas ejecutar basándose en las tareas declaradas en el archivo package.json. Al hacer push a GitHub, el entorno de CI recupera el caché remoto y reproduce los registros.
Bien, así que te he mostrado aquí en mi terminal que Tubo ya está almacenando algo en caché, ¿verdad? Vimos aquí que tenía algún caché antes. Así que déjame ejecutar un nuevo comando aquí. Voy a ejecutar de nuevo el comando pnpm test. Y ahora tenemos una salida diferente. Vemos el Tubo completo aquí, lo que significa que TuboRepo sabe que nada más cambió en nuestro paquete. Cambiamos el botón aquí, pero ya hemos ejecutado la prueba, ¿verdad? Así que ahora Tubo ya ha almacenado esto en caché y lo recuerda mientras no cambies el code. Si intento ejecutar el enlace de nuevo, lo mismo que hicimos antes, también es un Tubo completo. Eso es genial. No está ejecutando nada más. Es muy rápido. Ves, esto son 100 milisegundos. Ejecutó todo. Y luego también nos mostró todos los registros que tenía antes porque Tubo seguía almacenando y reproduciéndolos para ti, para que puedas ver lo que pasó antes.
Bien, así que hemos visto aquí cómo hacer desarrollo con Tubo, cómo podemos configurar nuestras tareas a través de los repositorios y cómo podemos ejecutar comandos de Tubo a través del repositorio. Así que lo que falta aquí es cómo Tubo sabe que necesita ejecutar una tarea de desarrollo o una tarea de lint o una tarea de prueba a través de nuestros paquetes. Lo único que tienes que asegurarte es que en tu paquete tienes esas tareas declaradas. Así que echemos un vistazo a nuestro paquete UI aquí y veamos cómo se ve el archivo package.json. Así que tenemos aquí el archivo package.json dentro del paquete UI, y aquí tenemos un montón de scripts. Pero observa que también tenemos un comando de desarrollo aquí, tenemos una prueba, y tenemos un lint. Y así es como Tubo sabe cómo invocar esos scripts. Siempre que tengan el mismo nombre en los paquetes, Tubo los ejecutará inmediatamente.
Bien, así que ahora sabemos cómo Tubo descubre esto a través de todos nuestros paquetes. Así que vamos a hacer commit de esto y luego vamos a hacer push a GitHub y ver cómo se comporta en nuestro entorno de CI. Así que estoy haciendo push directamente a la rama principal. ¿Y qué espero allí? Espero que mi entorno de CI, siendo consciente del caché, sea capaz de recuperar este caché remoto que generé localmente aquí, y simplemente reproduzca los registros. ¿Recuerdas que te dije que Tubo nunca hace el mismo trabajo dos veces? Así que también debería ser cierto para nuestro entorno de CI. Si ya hemos realizado una tarea, ya sea en nuestra máquina local o en un entorno de CI, entonces Tubo debería ser capaz de capturar este caché y simplemente reproducir los registros. Vamos a GitHub y veamos cómo se ve esto. Ahora estoy en la página de GitHub de este repositorio y puedo ver aquí que la acción ya ha sido ejecutada. Así que vamos a comprobarlo.
13. Ejecutando Tareas de CI con Tubo
El paso de verificaciones es crucial para ejecutar comandos pnpm. El script de CI, run pnpm ci, ejecuta el linting y las pruebas en paralelo respetando las dependencias. Tubo recupera el caché generado localmente y lo comparte entre los ejecutores de CI, incluso con diferentes sistemas de CI.
Así que tenemos una serie de pasos aquí, pero el más importante es el de las verificaciones. Ese es el que realmente ejecutamos nuestros comandos pnpm. Así que tenemos un comando aquí que ejecutamos. Vamos a aumentar un poco el tamaño de la fuente. Y luego tenemos un run pnpm ci. Y esos son nuestros scripts de CI. Echemos un vistazo a nuestro VS Code de nuevo, y entonces deberíamos ser capaces de ver el script de CI aquí. Ves que Tubo ejecuta lint y test. Así que está haciendo linting y test al mismo tiempo.
Volviendo a GitHub, echemos un vistazo a la salida aquí. Así que vemos UI build, vemos admin lint. Vemos UI lint, UI tests, un montón de salidas aquí que realmente esperamos que Tubo sea capaz de ejecutarlas en paralelo, pero también respetando las dependencias. Así que bajemos un poco más y veamos la salida. Tomó como 1.3 segundos ejecutar todas esas tareas. Y luego vemos Tubo completo aquí de nuevo, lo que significa que Tubo fue capaz de recuperar este caché que generé localmente aquí en mi máquina y luego compartirlo entre todos mis ejecutores de CI. Y si no estás usando GitHub actions, pero si estás usando GitLab CI, por ejemplo, eso funciona de la misma manera. Todavía puedes compartir tu caché a través de cualquier otro sistema de integración continua.
Y eso es todo. Y eso es lo que quería compartir con ustedes aquí. Muchas gracias. Y nos vemos por ahí.
Comments