Cómo Simplificar tu Codebase

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

Las codebases grandes y heredadas a menudo sufren de dependencias enredadas, falta de límites modulares y archivos "barrel" monolíticos que agrupan muchos módulos. Esto hace que la codebase sea difícil de entender, modificar y escalar. En esta masterclass, exploraremos estrategias para "desenredar el barrel" y simplificar una codebase compleja para prepararla para la migración a una arquitectura de monorepo.

Cubriremos técnicas para:

- Analizar tu código en busca de dependencias cíclicas

- Herramientas para ayudar a refactorizar el código

- Establecer pautas de codificación y automatización para controlar la complejidad de la codebase en el futuro

This talk has been presented at Node Congress 2025, check out the latest edition of this JavaScript Conference.

Tally Barak
Tally Barak
35 min
17 Apr, 2025

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Esta masterclass se centra en los desafíos de trabajar con grandes codebases, como límites de módulos poco claros, repetición de código y flujos desordenados. El código muerto se identifica como un problema importante que añade desorden y carga cognitiva a los desarrolladores. El árbol de sintaxis abstracta (AST) se presenta como una herramienta para acceder sistemáticamente al código. Se recomienda TSmorf para encontrar y eliminar código muerto mediante la traversión y manipulación del AST. Las dependencias cíclicas se discuten como otro problema, y se sugiere MADGE como una herramienta para identificar y resolver referencias circulares. Los archivos barrel se presentan como un método para organizar el código y resolver referencias cíclicas. Se explica el proceso de reemplazar importaciones y eliminar llamadas vacías. Las conclusiones clave incluyen la importancia de una buena arquitectura en capas, eliminar código muerto, romper dependencias cíclicas y reducir archivos barrel.
Available in English: How to Simplify your Codebase

1. Understanding the Problem with Large Codebases

Short description:

Esta masterclass está dirigida a personas que trabajan en grandes bases de código. Los signos de una mala arquitectura incluyen límites de módulo poco claros, repetición de código y flujos desordenados. Estos problemas dificultan realizar cambios, ralentizan la velocidad de los desarrolladores y conducen a errores desconocidos.

Así que esta masterclass, chicos, está dirigida a personas que están trabajando en grandes bases de código. Y grandes bases de código que han estado alrededor durante algunos años y probablemente han sido trabajadas por múltiples desarrolladores podrían parecerse a algo que podría recordarte a algo que se ve aquí. Y luego vas a tu gran base de código y vas y haces un cambio menor que con suerte no debería hacer nada. Pero esto es lo que está sucediendo. Todo se bloquea. Tu CI está en rojo, tus pruebas están fallando, tal vez la aplicación no se compila y así sucesivamente.

Y el término técnico que describe esta situación se llama textura crappy. Y esto es una señal de que hay un problema con la arquitectura de tu aplicación. ¿Cuáles son las señales que vemos de mala arquitectura? La primera y creo que la más crítica es que no hay límites de módulo claros. No estamos seguros de lo que hace cada módulo, de qué es responsable, y así sucesivamente. Hay mucha repetición de código. Simplemente porque no está claro qué está haciendo qué, podrías encontrarte escribiendo el mismo código en diferentes lugares. Con suerte, funciona igual, pero es más probable que esté haciendo cosas diferentes. Flujos desordenados.

Si estás tratando de entender un flujo en el sistema, podrías encontrarte navegando a través de decenas de archivos y tratando de entender qué está llamando a qué, cómo va, dónde están los ifs y así sucesivamente. Y eso hace que sea muy difícil hacer cambios. Ralentiza la velocidad de los desarrolladores. Es difícil refactorizar. Si quieres hacer un cambio, incluso para intentar mejorar algo porque estás tratando de hacerlo un poco mejor, te encuentras afeitando yak y realmente no puedes hacer el cambio. Y eventualmente, te da una enfermedad de la que todos sufrimos, errores de los que no tienes idea de dónde vinieron.

2. Addressing the Problem of Dead Code

Short description:

La presión del tiempo, los requisitos cambiantes, la comprensión incompleta, la madurez de la tecnología y los factores humanos contribuyen al problema de las grandes bases de código. En lugar de arrancar todo y empezar desde cero, sugiero abordar problemas específicos. En esta masterclass, me centraré en el problema del código muerto, que añade desorden y carga cognitiva a los desarrolladores.

de la que todos sufrimos, errores de los que no tienes idea de dónde vinieron. ¿Por qué está sucediendo esto? ¿Cuáles son las razones? La primera, y creo que la más común es la presión del tiempo. Conoces el término de hagámoslo rápido y sucio. Puedo decirte que por muchos años de experiencia en software. Nunca es rápido y siempre es sucio, y generalmente trae una tecnología que toma mucho tiempo arreglar. Los requisitos cambian. Esto es normal. Esto es parte del flujo regular del desarrollo de software, que obtienes un nuevo requisito y luego cambia. Ya no necesitamos el anterior, pero tal vez no tengamos tiempo para venir y repensar toda la forma en que lo implementamos. Así que solo estamos parcheando el software con diferentes cosas en diferentes lugares diciendo, está bien, esto es lo que vamos a hacer.

Comprensión incompleta. Esto también está sucediendo. Cuando comienzas, hay una nueva característica. Tal vez todavía seas una empresa relativamente joven. No entiendes completamente qué va a ser la característica y cuáles son las obstrucciones que vamos a necesitar para dejarlo claro. La tecnología madura. Lo hemos visto. Estás trabajando en, comienzas con una cierta versión de, digamos, Node y luego crece y de repente tienes ESM y tienes async await y ese tipo de cosas, pero obviamente no tienes el tiempo para volver y refactorizar toda la base de código. Y la última cosa es, llamémoslo los factores humanos.

También los desarrolladores probablemente no nacen con todo el conocimiento para hacer las cosas de la manera correcta, para escribir el código perfectamente, y con el tiempo maduramos y vemos más y más cosas que sabemos cómo mejorar. Está bien, así que sí, tenemos una base de código problemática, Tali. ¿Qué sugieres hacer? ¿Deberíamos simplemente venir y arrancar todo y reescribir desde cero? Bueno, eso podría ser agradable, pero es muy probable que no puedas hacer eso. Así que en su lugar, déjame sugerir algo más. Mi nombre es Tali Barak. Soy arquitecto de software en Ubiquit y esta masterclass se llama Log Stock and Barrel. El nombre se revelará más tarde y está hablando sobre la reestructuración de grandes bases de código. El primer problema, voy a abordar tres problemas que pueden ayudarte a crear una mejor arquitectura para tu aplicación y el primero será sobre el código muerto. El código muerto es código que nunca se ejecuta. Existe en el sistema porque alguien lo puso allí hace cinco años o más y nadie ha notado que ya no se está utilizando. ¿Por qué es eso un problema? Porque de nuevo, esto es desorden.

3. Understanding Dead Code and the AST

Short description:

El código muerto crea confusión, carga de mantenimiento e impacta el rendimiento y el tamaño. Un ejemplo de código muerto es una función que nunca se utiliza, incluso si está exportada. Para acceder sistemáticamente a nuestro código, utilizamos un árbol de sintaxis abstracta (AST).

Crea una carga cognitiva en los desarrolladores. Crea mucha confusión. Estás tratando de buscar algo y encuentras cinco funciones que están respondiendo a ello y luego comienzas a indagar solo para descubrir tres horas después que este código en realidad nunca se utiliza. Eso es obviamente también una carga de mantenimiento por la misma razón, estás yendo y tratando de arreglar algo y luego te das cuenta, bueno, esto no está haciendo nada. Y también rendimiento y tamaño. Si estás agrupando o si necesitas construir y así sucesivamente, el código muerto está ahí. Tu agrupador o tu aplicación, tu tiempo de ejecución lo está mirando. Está tratando de interpretarlo.

Pero todo eso se está haciendo en vano. Veamos un ejemplo de cómo se ve un código muerto. ¿De acuerdo? Así que supongamos que tengo este archivo, somefile.js. También puede ser JS y tengo una función foo y esta función está haciendo algo, lo que sea. En algún lugar más abajo en el mismo archivo estoy llamando a foo tal vez en múltiples lugares y así sucesivamente y todo se ve genial. Lo siguiente que hago es, como parte del mantenimiento, los cambios en el código, elimino estas instancias. Ahora esto es fácil porque si tengo linting en mi aplicación, realmente me gritará y dirá, mira, esto no se usa. Deberías eliminarlo. Así que eso funciona genial. Eso eliminará algo de código muerto. Pero, ¿qué pasa en este caso? ¿Qué pasa si esta función está siendo exportada? Incluso si no se utiliza en el archivo, mi linter estará totalmente en silencio y no me dirá si se está utilizando o no. ¿De acuerdo? Porque no lo sabe. Tal vez esté en otro archivo.

¿Cómo lo solucionamos? Y el primer pensamiento es, está bien, hablemos con el dios de la IA y pidámosle que lo solucione. Pero la verdad es que incluso la mejor herramienta y la herramienta moderna no son muy buenas para revisar nuestra antigua base de código y encontrar cosas que no se están utilizando. Lo que puede ayudarnos es intentar abordarlo programáticamente. Y ¿qué quiero decir con eso?

4. Using AST and tsmorf to Find Dead Code

Short description:

Para acceder a nuestro código de manera sistemática, utilizamos el Árbol de Sintaxis Abstracta (AST), que es la base de cada compilador. Representa nuestro código como un árbol de diferentes elementos, como declaraciones de funciones, palabras clave de exportación, identificadores, bloques y más. Usando un visor de AST, podemos explorar los detalles de cada elemento. Sin embargo, trabajar con el AST directamente puede ser un desafío debido a su estructura de árbol. Para simplificar esto, podemos usar una herramienta llamada tsmorf, que proporciona APIs para recorrer y manipular el AST. Importemos el proyecto tsmorf para escribir la función que nos ayudará a encontrar código muerto.

Para acceder a nuestro código de manera sistemática, estamos utilizando algo que se llama AST. Esta es la base de cada compilador. Es un árbol de sintaxis abstracta. Y esta es la forma en que nuestro compilador o servicio de lenguaje o todo está entendiendo nuestro código. Así que a la izquierda, tengo una función muy simple. Que básicamente no hace nada. Y si utilizo un visor de AST de TypeScript, y por cierto, AST de TypeScript, cada vez que hablo sobre TypeScript, porque este es un superconjunto de JavaScript, también puedes usarlo para superscript. No va al revés. Pero si estás usando JavaScript, está perfectamente bien. Así que esta es mi función. Y esta es la forma en que el compilador la ve. La ven como un árbol de diferentes elementos. Así que tenemos declaración de función, palabras clave de exportación, identificador, bloques, literal de cadena y así sucesivamente. Todo está definido aquí. Y si nos enfocamos en un cierto elemento, en este caso me estoy enfocando en log, que es un identificador, puedo ver muchos más detalles sobre exactamente dónde comienza, dónde termina, cuántos hijos tiene, y así sucesivamente. Y puedes usar este árbol de sintaxis abstracta. Esto es algo que el compilador de TypeScript, por ejemplo, está utilizando para enviar, y también lo tenemos para JS. Pero es muy difícil trabajar con ello. Es un árbol. Y sabemos que cuando necesitamos recorrer un árbol, necesitamos visitar todos los nodos y así sucesivamente. Y para eso, tenemos un hermoso truco. Esta es una herramienta que se llama tsmorf. Esta es la URL donde la encuentras. Y en realidad es un resumen de las APIs que se utilizan para recorrer archivos AST. Así que configura la navegación y manipulación del AST de TypeScript. Como dije, también JavaScript. Y esta biblioteca envuelve la API del compilador. Así que genial. Vamos a usar tsmorf para escribir la función que va a encontrar ese código. Así que lo primero que hacemos, necesitamos importar el proyecto.

5. Finding and Removing Dead Code with TSmorf

Short description:

Para encontrar código muerto en tu proyecto, puedes usar tsmorf y el AST. Comienza agregando todos los archivos fuente que deseas verificar, e ignora cualquier archivo que no quieras incluir. Itera a través de los archivos fuente e identifica las funciones en cada archivo. Usa la utilidad 'find references as nodes' en TSmorf para encontrar dónde se está utilizando cada función. Si una función no tiene referencias, es probable que sea código muerto y se pueda eliminar. Este proceso también se puede aplicar a variables. Además, se puede utilizar IA para automatizar modificaciones de código, pero ten en cuenta el uso predeterminado del compilador de TypeScript y considera usar TSmorf para obtener mejores resultados.

que hacemos, necesitamos importar el proyecto. También el archivo fuente es un buen tipo, pero es importante.

Así que tienes el archivo fuente, el proyecto, y creamos un nuevo proyecto, un nuevo proyecto tsmorf. El siguiente elemento es que vamos a agregar todos los archivos fuente que queremos verificar. Así que estamos agregando todo. En este caso, nuevamente, es todo de TS bajo source, pero obviamente, puedes ajustar eso a tus necesidades específicas. Puedes tener múltiples ubicaciones. Puede obtener un array. Así que obtienes el proyecto con todos los archivos fuente que has importado. Por cierto, también puedes ignorar cosas como que no quieres verificar tus archivos de prueba , por ejemplo. Así que puedes ignorar test.

tf. La siguiente cosa, vamos a iterar a través de todos los archivos fuente que hemos visto previamente. Y para cada archivo fuente, vamos a obtener todas las funciones que existen en este archivo específico. Luego estamos iterando sobre las funciones en el archivo. Y lo que estoy haciendo aquí es que estoy usando una gran utilidad. Este es el tipo de utilidad en la que TSmorf sobresale, que se llama find references as nodes. Y eso me dará todas las referencias de dónde se está utilizando esta función. Y luego, en este caso, si la longitud del nodo de referencias es cero, lo que significa que no hay referencias a este código, o como yo, en este caso, yo puedo simplemente hacer un console log y especificar qué archivo tiene la función y cuál es el nombre de la función. Y más adelante, puedes automatizar la eliminación o puedes hacer algunas verificaciones adicionales, asegurarte de que sea correcto. Y manualmente o porque básicamente solo se trata de eliminar una función. Así que tal vez quieras verificarlo dos veces y luego eliminarlo manualmente. Así que ese es un ejemplo de cómo podemos deshacernos de los códigos muertos. Solo quiero mencionar aquí que podemos hacer eso también para variables, no para funciones. TSmorf tiene todas estas utilidades que podemos verificar solo para las exportaciones y no todas las funciones que están definidas en el archivo. Porque ESLint encontrará la local. Podemos mejorarlo si estamos trabajando en OOP, programación orientada a objetos de una manera. Luego podemos extenderlo también para clases, para métodos, para miembros. Y por cierto, este es el lugar donde el tree shaking no está haciendo un gran trabajo. Así que si tienes una clase con, no sé, 30 o 40 métodos y la mitad de ellos no se están utilizando, esto es un gran dolor para tu rendimiento. Y la última cosa es que dije que la IA no es muy buena para revisar toda tu base de código, pero la IA es extremadamente buena en escribir este tipo de función, lo que se llama modificación de código.

6. Identifying and Resolving Cyclic Dependencies

Short description:

Las dependencias cíclicas en tu código pueden causar un acoplamiento estrecho, mayor complejidad y errores en tiempo de ejecución. MADGE es una herramienta que puede ayudarte a encontrar referencias circulares y generar gráficos de llamadas. Usando MADGE, puedes identificar y resolver dependencias circulares en tu código. Otra opción es usar el plugin ESLint Enforce Module Boundaries en el espacio de trabajo de Nx para informar sobre referencias circulares.

Y obviamente puedes hacer mucho más. Y veremos otro ejemplo. Está bien. Así que ese código es un problema.

Aquí hay otro que, debo admitir, es incluso más doloroso. Y esto son las dependencias cíclicas. Así que esta es tu arquitectura, o esta es en realidad una porción muy pequeña, porque en una base de código grande probablemente tengas cientos de paquetes. Y en una buena arquitectura, las llamadas deberían ser unidireccionales. Significa que deberías llamar a algo que llama a algo, generalmente está bien organizado en capas, así que la capa superior puede ver las capas debajo de ella, pero las capas inferiores no pueden mirar las capas de arriba. Esto también ayuda con las abstracciones.

Y esto se ve muy bien, pero luego alguien va y añade una llamada del paquete 5 al paquete 3, y como puedes ver en el lado derecho aquí, en realidad creamos un círculo, una dependencia circular. Y el círculo de problemas está causando que el código esté muy acoplado. Está aumentando la complejidad dentro del código. Es muy difícil de refactorizar, y también puede ocurrir errores en tiempo de ejecución. Este es un ejemplo. Es bastante simple. Ves aquí que tenemos dos módulos, la función B está llamando, lo siento, la función A está llamando a la función B, y la función B está llamando a la función A. Generalmente, esto no es cómo va a ser en tu código, es probablemente que va a haber cinco módulos diferentes.

Está bien. Aquí tengo una sugerencia muy corta. Usa MADGE. MADGE es una gran herramienta que está haciendo, puede encontrar estas referencias circulares. También puede generar gráficos de las llamadas en tu aplicación, pero tengo que decir que cuando tienes una base de código grande, estos gráficos generalmente no son muy utilizables. Podrías necesitar proyectarlos en una cartelera para poder ver algo. Así que aquí hay un ejemplo. Ejecutas npx madge, menos C significa encontrar circulares. Le das un punto de entrada, procesará el archivo, y señalará, sé que hay cuatro, pero solo quería mostrar un ejemplo. Así que los servicios comunes, MongoDB está llamando al ayudante de MongoDB, que está llamando al ayudante de configuración, que a su vez está llamando de vuelta al archivo de MongoDB. Así que esa es una opción. Otra opción que mencioné rápidamente aquí, si estás usando Nx, y no discutiremos Nx, pero si estás usando el espacio de trabajo de Nx, también tiene un gran plugin ESLint que se llama Enforce Module Boundaries, que también informará sobre referencias circulares.

7. Resolviendo Referencias Cíclicas y Usando Archivos Barrel

Short description:

Para resolver referencias cíclicas, extrae la funcionalidad compartida y llámala para ambos modelos. Los archivos barrel, que sirven como archivos índice, pueden ocultar la estructura interna y facilitar la refactorización sin afectar a los consumidores externos. Sin embargo, pueden aumentar la superficie de importación y llevar a problemas de rendimiento. Usé la herramienta tsmove para arreglar un ejemplo extrayendo funciones a un módulo separado y creando un archivo índice específico de dominio. Al mover archivos, ten en cuenta los posibles problemas con las importaciones generadas por el IDE. Para actualizar importaciones en múltiples archivos, usa la función runReplaceImports en tsmove.

La solución aquí es, para ser honesto, un poco compleja. Así que si tengo esto, probablemente necesitaré extraer la funcionalidad compartida y luego llamar a esta funcionalidad compartida para ambos modelos. Es más fácil dibujarlo que hacerlo en realidad. Puede ser bastante complejo entender cuál es la funcionalidad.

Está bien. Referencias cíclicas. Ahora cambiemos al archivo barrel, y aquí es de donde viene el nombre. Un archivo barrel, el logstock y barrel significa todo incluyendo todo, y el archivo barrel es básicamente un archivo índice desde el cual exportas múltiples funciones. Así que se verá algo así. Tengo la función A, B, C, lo que sea que esté exportando, y luego en tu archivo, vas a importar estas funciones solo desde el archivo índice y usar lo que necesites. Cuando hablamos de archivos barrel, tiene un muy buen punto. Ocultará la estructura interna. Así que no cada módulo que está importando desde este módulo necesita conocer la estructura interna, y te da cierta libertad para hacer refactorización interna sin afectar a los consumidores externos. Pero también tiene desventajas. Lo malo es que aumenta la superficie de importación, así que intentas importar una sola función y terminas importando 500 archivos.

Esto puede tener un gran impacto en el rendimiento, y porque los archivos barrel importan muchos archivos, tienes una mejor oportunidad de obtener referencias cíclicas porque simplemente estás importando tantos archivos. Así que quiero mostrar un ejemplo de cómo uso tsmove nuevamente en código para arreglar un ejemplo. Así que nuevamente, tengo aquí una versión ligeramente diferente de mi importación yendo desde una exportación diferente, y luego en mi archivo, estoy importando la función 1, 6 y 8 desde este archivo índice. Y ahora digamos que miré el código y dije, está bien, así que la función 7 y la función 8 del módulo D, quiero extraerlas a un módulo separado. Quiero sacarlas de estos utils y tenerlas en su propio módulo. Y creé un archivo índice de dominio D con el módulo D, y exporto solo estos archivos. También moví los archivos. Ahora, la gente podría venir y decir, mira, cuando mueves los archivos, tu IDE puede arreglar todas tus importaciones por ti. Cierto, pero cuando trabajas con bases de código grandes, probablemente va a crear referencias muy malas, especialmente si estás usando un atajo para la ruta. Podría usar una ruta relativa en lugar del atajo para la ruta. Está bien, así que ahora en mi archivo, quiero cambiar la función 1, 6 y 8 de utils y dividirla en dos importaciones, una todavía de utils y otra de la función 8. Si esto es solo en un archivo, puedes hacerlo manualmente, no hay problema. Pero el problema es que probablemente tienes cientos de importaciones para estos utils por todas partes, y hacerlo uno por uno puede ser realmente tedioso. Así que, ¿qué hacemos? Creamos una función que se llama runReplaceImports, está bien, usando nuevamente tsmove.

8. Reemplazando Importaciones y Eliminando Llamadas Vacías

Short description:

La función recibe cuatro parámetros: ruta del proyecto, archivo a cambiar, especificador antiguo y especificador nuevo. Itera a través de los archivos fuente, filtra las declaraciones de importación, elimina la importación especificada, verifica si la nueva importación ya existe y agrega la importación deseada. Si la importación antigua queda vacía, se elimina.

Recibirá cuatro parámetros. La ruta del proyecto, dónde quiero cambiar el archivo, el nombre de la importación, el antiguo especificador y el nuevo especificador, qué función quiero mover de dónde a dónde. Ahora estoy creando un nuevo proyecto y importando todos los archivos desde la ruta del proyecto como hemos visto antes. Luego itero a través de todos los archivos fuente, y para cada archivo fuente, estoy reemplazando las importaciones. Y más adelante, lo guardo y puedo ejecutar esta función. Obviamente, esto es solo el envoltorio.

La clave aquí es qué hago en la importación de reemplazo. Así que nuevamente, veamos qué queremos hacer. Quiero tomar de algún archivo los utils, y quiero dividirlo en dos importaciones diferentes. Así que, y aquí en la parte inferior puedes seguir lo que estoy haciendo en el código. Así que lo primero que hago es obtener las declaraciones de importación de cada archivo. Estoy revisando cada archivo y obteniendo las declaraciones de importación. Probablemente obtendré muchas importaciones. Lo siento por eso. Y luego todo lo que quiero hacer es filtrar ellas. Quiero filtrar las declaraciones de importación para encontrar solo la que tiene el especificador antiguo. Nuestro especificador antiguo es utils, y eso significa que solo obtendré esta línea aquí.

Y ahora para, sí, y ahora para cada declaración de importación, lo que voy a hacer es que voy a encontrar la importación nombrada, la importación que quiero mover. En nuestro caso, esta es la función ocho. Si la encontré porque podría no tenerla, obtendré el nombre y lo eliminaré de la importación. Así que obtendré algo como eso. La función ocho fue eliminada. A continuación, quiero crear una nueva importación. Quiero verificar si la nueva importación ya existe. Así que estoy verificando el nuevo especificador, veo si ya existe. Si la encuentro, todo lo que necesito hacer es agregar la importación que quiero mover en la función ocho nuevamente. Solo quiero agregarla. Así que puedes ver aquí que ya tenía la función suma, y ahora tengo la función ocho. Si no existe, lo que hago es que en realidad agrego una nueva declaración de importación, función ocho de dominio D, y tengo mi nueva importación. Y la última cosa que quiero hacer aquí es si la declaración de importación, la antigua, la que obtuve de los utils, ahora tiene una longitud de cero, la importación nombrada, lo que significa que es una vacía, quiero eliminarla para no tener llamadas vacías en mi archivo y se irá.

9. Conclusiones Clave para Construir Software Grande

Short description:

Necesitamos una buena arquitectura en capas para construir software grande. Las capas claras promueven la modularidad, la claridad del código y la velocidad de desarrollo. Los tres consejos mencionados son eliminar código muerto, romper dependencias cíclicas y reducir archivos barrel. Gracias.

Así que una rápida conclusión de esta masterclass. Queremos tener una buena arquitectura en capas. Esta es la manera de construir software grande. Queremos asegurarnos de que tengamos capas claras. Cada una ve la que está debajo, pero no, no está inconsciente de lo que está encima. Una buena arquitectura ayuda a la modularidad, la claridad del código, la velocidad de desarrollo, cuando es, podemos agregar rápidamente más elementos, y por supuesto es más fácil de mantener y escalar.

Y los tres consejos que mencionamos, eliminar código muerto, obtendrás una base de código lineal, romper la dependencia cíclica para la modularidad, y reducir el archivo barrel para claridad y eficiencia.

Y eso es todo. Muchas gracias, Guy. Gracias por asistir a mi masterclass. Adiós.