Lecciones para Construir Bases de Código Resilientes

This ad is not shown to multipass and full ticket holders
JSNation US
JSNation US 2025
November 17 - 20, 2025
New York, US & Online
See JS stars in the US biggest planetarium
Learn More
In partnership with Focus Reactive
Upcoming event
JSNation US 2025
JSNation US 2025
November 17 - 20, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

La cruda realidad es que el desarrollo de software es desordenado. Comienzas con las mejores herramientas, la mejor arquitectura y las mejores intenciones, pero la calidad inevitablemente decae con el tiempo. El código frontend es particularmente frágil en el tiempo, ya que se encuentra en la intersección de producto, diseño e ingeniería. Hace un tiempo comencé a preguntarme si todas las bases de código están destinadas a fallar y volverse obsoletas. Luego comencé a recopilar lecciones de éxitos y fracasos pasados y noté cuán importante era la resiliencia para el éxito de un proyecto a largo plazo.


La resiliencia es la capacidad de una base de código para sobrevivir a oleadas de desarrollo caótico y cambios no planificados. La resiliencia tiene menos que ver con las herramientas y frameworks que implementas, y más que ver con la disciplina de escribir y mantener un código limpio. ¿Alguna vez te has preguntado cuánto trabajo se requerirá para actualizar el código que estás escribiendo hoy, dentro de 6 meses? Veamos si podemos responder eso con un simple: "no mucho".

This talk has been presented at JSNation 2024, check out the latest edition of this JavaScript Conference.

Alex Moldovan
Alex Moldovan
29 min
13 Jun, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Las bases de código degradan con el tiempo, por lo que es importante construir una capa protectora y aceptar imperfecciones. La colocación y dejar rastros en el código son clave para una mejor comprensión. Las estrictas comprobaciones de nulos y la tipificación explícita de TypeScript pueden mejorar la confiabilidad del código. Las pautas y convenciones de nomenclatura son cruciales para mantener una arquitectura consistente y escalable. La complejidad del control de versiones no se ve significativamente afectada al tener múltiples componentes en un archivo.

1. Understanding Resilient Code Bases

Short description:

Estoy aquí para hablar desde el rol de ingeniero de productos en Code Sandbox. El problema con las bases de código es que se degradan con el tiempo. ¿Cómo te aseguras de que estas bases de código soporten este estrés?

¡Hola a todos! Wow. Estoy sorprendido con tanta gente aquí. Estaba bromeando, como, el mayor miedo que tengo con un evento de múltiples pistas es estar frente a cinco personas en la primera fila y hablar. Pero, sí, muchas gracias por unirse a esta sesión. Como mencioné antes, vengo de Rumania, de una ciudad llamada Cluj. Soy uno de los organizadores de JS Heroes. No estoy seguro si alguien ha oído hablar de JS Heroes o ha estado en JS Heroes. Bien. Unas pocas manos, genial. Sí. Ven a encontrarme después si quieres hablar más sobre conferencias y organización y eventos de community. Encantado de charlar hasta la noche sobre eso, si quieres. Hoy estoy aquí para hablar desde el rol de ingeniero de productos en Code Sandbox. Si quieres seguir las diapositivas, ya están en línea en bit.ly. Puedes obtenerlas más tarde. Hay un par de referencias a lo largo de las diapositivas. No necesitas tomar fotos ni nada. Estoy hablando desde la experiencia de un ingeniero de productos y básicamente trabajando en Code Sandbox durante los últimos cuatro años, trabajando en empresas anteriores en roles similares, y lidiando con bases de código, ¿verdad? El problema con las bases de código es que se degradan con el tiempo. Esto es simplemente inevitable. ¿Qué quiero decir con bases de código resilientes? Hablemos un poco sobre por qué esto es incluso algo. Cuando trabajas en una empresa de productos, o trabajas en general en un proyecto de tamaño mediano, una startup, un proyecto a gran escala, la mayoría de las veces, la prioridad se va a desplazar hacia las características, las necesidades del usuario, las necesidades del negocio, no tanto en el lado de la ingeniería. Seamos honestos, no tienes tiempo cada seis meses para reescribir todo o repensar la architecture o construir lo que sea el framework más popular en la actualidad. Esto me hizo pensar a lo largo de los años. Comencé a recopilar estas lecciones de construir estas bases de código. ¿Cómo te aseguras de que estas bases de código soporten este estrés? Básicamente, si tomas el código, la base de código que tienes, con el tiempo, hay presiones que se aplican a tu base de código, ¿verdad? Esas presiones pueden ser cambios de equipo, personas que inicialmente construyeron la architecture tal vez ya no forman parte del equipo. Puedes tener cambios de prioridades en la empresa donde la base de código tal vez no esté en un rol central en este momento. Puedes tener el roadmap del producto que ejerce mucha presión nuevamente sobre la base de código, características que ni siquiera consideraste al principio cuando escribiste las primeras líneas de código que ahora se han convertido en la parte central de tu base de código. El negocio puede pivotar hacia algo más pero aún estás utilizando parte del trabajo fundamental que construiste al principio. Eso se vuelve cada vez más interesante con eso.

2. Mantener Bases de Código Resilientes

Short description:

El código se degrada con el tiempo, ¿cómo lidiar con ello? Construye una capa protectora alrededor de tu código. Acepta la imperfección y concéntrate en hacer un trabajo lo suficientemente bueno. La colocación es importante tanto para escribir como para leer código.

Además, con el paso del tiempo, como dije, el code simplemente se degrada, tal vez se acumule una profundidad técnica, eso es inevitable, ¿entonces cómo lidiar con esto?

El problema es que cuanto más tienes todas estas diferentes presiones en tu code, es más probable que la base de code se desmorone o se convierta en esa cosa legada a la que todos odian volver y tener que mantener algo en ella. Entonces, sí, el objetivo aquí es hablar de cómo puedes mejorar esto. ¿Cómo puedes construir esta capa protectora alrededor del code que escribes o qué cosas puedes hacer para asegurarte de que con el tiempo, ya sabes, las bases de code mantengan esta resiliencia y sobrevivan a este tipo de presiones externas?

La lección número uno es aceptar la imperfección, y lo que quiero decir con eso es que perfecto, en nuestro caso, es el enemigo de lo bueno, porque tienes que hacer un trabajo lo suficientemente bueno. No estoy diciendo imperfección en el sentido de que puedas, ya sabes, es mejor hacer como spaghetti code y simplemente escribir todo donde quieras. Tienes que hacer un trabajo lo suficientemente bueno para la base de code, ¿verdad? Y cuanto más sigas esa idea de que, okay, esto, ya sabes, la architecture necesita ser perfecta, las capas deben estar claramente separadas, ya sabes, las guidelines deben ser estrictamente, ya sabes, respetadas, más lucharás contra este tipo de, ya sabes, la presión inevitable que se acumula en la base de code.

3. Manejo de Imperfecciones y Colocación

Short description:

Mostraré un par de ejemplos de código de producción donde aceptamos imperfecciones. Un ejemplo es usar una búsqueda en línea en lugar de expandir la API actual. Otro ejemplo es introducir condicionales para borradores en lugar de hacer cambios en todas las capas de la aplicación. La colocación es importante tanto para escribir como para leer código, permitiendo una fácil adición de características y reduciendo la necesidad de múltiples archivos.

Y aquí hay un par de ejemplos. Voy a ir directamente al code. Voy a mostrar un par de cosas del code de producción, así que, ya sabes, no es como si la mayoría de estas cosas fueran falsas o algo así. Solo quiero mostrarte un par de ejemplos.

Realmente no importa tanto el code, solo quiero resaltar las cosas que hice en los últimos años o con el equipo para, ya sabes, cosas donde aceptamos cosas que no son perfectas, ¿verdad?

En este caso, recientemente agregué esta búsqueda a un punto final para obtener, ya sabes, plantillas para el editor de sandbox de code cuando quieres crear algo nuevo. Y esto no pasa por nuestra capa de abstracción regular de la API que va al backend, establece encabezados, establece authentication y demás. Esto es solo una búsqueda en línea. Y la decisión de hacerlo aquí es que realmente no queríamos, ya sabes, expandir la abstracción de la API actual, así que esto no es ideal. Por supuesto, solo está escrito aquí en una función, pero funciona, y es algo único, y es una pequeña imperfección que aceptas, es una excepción a toda la architecture de la aplicación, y, ya sabes, la aceptas y sigues adelante.

Otro ejemplo es cuando introdujimos esta idea de un borrador, ¿verdad? Y el borrador viene a través de nuestro sistema de permisos que tiene como posibles valores 0, 1, 2, niveles de permiso, el borrador es algo especial en el lado del cliente. Así que en lugar de hacer cambios en todo el backend y en todas las capas de la aplicación, comenzamos a introducir estos condicionales en el code para, ya sabes, funcionar de manera diferente para los borradores, que eran una preocupación muy específica del cliente. Nuevamente, no importa, no necesitas entender el code, es solo el principio de que un modelo de architecture imperfecto te permite tomar atajos razonables cuando sea necesario, se toleran excepciones pero se documentan bien cuando ocurren, y una architecture muy importante no debe obstaculizar tu camino. Si necesitas construir algo, si necesitas enviar algo rápidamente, está bien tomar estas excepciones, tomar estos atajos, y no tienes que luchar contra la architecture o las limitaciones de tu sistema para hacerlo.

La lección número dos está relacionada con la colocación. De hecho, escribí un artículo sobre esto si quieres leer más sobre la colocación. Lo escribí especialmente desde la perspectiva de cómo las DevTools y los frameworks manejan la colocación y cómo nos ayudan en la fase de escritura del code. También quiero describir rápidamente esto como lo que quiero decir con la fase de escritura y lectura. Entonces el code, ya sabes, toma el ciclo de vida de un code, tiene una fase de escritura donde entras y no sé cómo se ve esta barra de desplazamiento. De acuerdo. No era así. Escribes un code y lo subes a Git o algo así, ¿verdad? Esta es la fase de escritura. Esto es cuando, sí, esta es la fase de escritura. En la parte de lectura, alguien más viene y lee ese code, ¿verdad? Alguien más puede volver a leer ese code, y tú puedes volver y leer ese code después de un tiempo, y veremos eso en unos minutos.

Entonces la idea es que la colocación ayuda tanto al escribir el code como al leer el code. Al escribir el code, puedes pensar en lo útil que es tener herramientas como en este caso JSX y Tailwind, ¿verdad? Estás escribiendo un fragmento de code. Es como si estuvieras escribiendo a mano y no levantaras la mano, ¿verdad? Estás describiendo la semántica, estás describiendo el estilo, estás describiendo la lógica condicional en función de la cual algo se renderiza o no, y esto es una colocación muy detallada y esto es realmente útil en la fase de escritura. También puedes pensar en cuando ya tienes un gran fragmento de code, como un gran conjunto de componentes, escribir algo nuevo, agregar una característica no requiere que vayas a múltiples lugares e introduzcas múltiples archivos nuevos. Puedes poner todo ahí. En el lado de la lectura, vamos a tener que ver algo de code aquí. En el lado de la lectura, nuevamente, la colocación en pequeños fragmentos ayuda mucho, pero también quiero resaltar algo que encontré muy útil recientemente.

4. Reusabilidad y Dejar Rastros

Short description:

Al manejar bases de código, es útil mantener los componentes junto a sus componentes principales, incluso si el archivo se vuelve largo. La reusabilidad tiene aspectos tanto positivos como negativos, con beneficios como la deduplicación y la separación de preocupaciones, y desventajas como el código zombie y la abstracción innecesaria. La propagación de cambios y la necesidad de comprender el código reutilizado deben tenerse en cuenta al decidir sobre la reusabilidad. Dejar rastros en el código es importante para una mejor comprensión.

Cuando tienes una base de código más grande que, nuevamente, crece con el tiempo, lo que encontré útil es no extraer todos tus componentes en archivos diferentes. Este es uno de los problemas con las aplicaciones y con las bases de código a medida que crecen, ¿verdad? Tiendes a construir cada componente, tienes cada componente en un archivo nuevo. En este caso, por ejemplo, el encabezado del componente del panel de control aquí, nuevamente, el code no es importante, es más como un concepto aquí, así que hay un encabezado exportado desde este archivo, pero este archivo también contiene, de hecho, puedes verlo aquí, contiene otro componente llamado grupo de entrada de búsqueda. Esto suena como el tipo de componente que quieres extraer, ¿verdad? Pero es muy específico de ese encabezado. Se usa solo una vez allí, por lo que la decisión es que cuando esto sucede, mantienes los componentes junto al componente principal. Incluso si este archivo se vuelve largo, y puedo mostrar otro ejemplo aquí donde tenemos los planes de precios en la página de pago, y esto es como una UI compleja con todo tipo de cosas. Nuevamente, hay toneladas de componentes aquí definidos como puedes ver en el mismo archivo. Lo importante es que el archivo exporta un solo componente. Todo lo demás es como detalles del componente principal y no se abstrae, y no se lleva a algún lugar para ser reutilizado más tarde. Esto, nuevamente, volviendo a la lección, es la colocación en el sentido de que cuando escribes el code, lo escribes en un solo archivo siempre y cuando la preocupación sea la misma. Simplemente estás construyendo este nuevo componente, incluso si se descompone en varios componentes o tal vez tiene algunas funciones de utilidad.

Desde la perspectiva de lectura, también es muy beneficioso porque cualquiera que venga, y cuando sepa que tiene que cambiar algo en la página de planes, no tiene que buscar el componente real o el componente más pequeño que representa o tiene el cambio que tienen que introducir. Puedes estar viendo esto y pensando, ¿ok, esto es un caso en contra de la reusabilidad? ¿No deberías reutilizar demasiado code en las bases de código? La respuesta es sí y no. Como siempre, depende porque la lección número tres es que la reusabilidad es una espada de doble filo. Tiendes a pensar que todo, cuanto más reutilizas cosas, cuanto más abstraes utilidades y componentes, mejor es para la base de código a largo plazo. Pero yo argumentaría que hay una parte buena y una parte mala en la reusabilidad y tienes que equilibrarlas. En el lado positivo, tienes cosas como abstraer una caja negra, tienes deduplicación, obviamente no te repites y tienes separación de preocupaciones cuando lo haces bien. En el lado negativo, tienes código zombie, ¿verdad? Suponiendo que algunos de esos componentes más pequeños están escritos en archivos separados, por alguna razón, el archivo principal cambia, ya no usa uno de los componentes pequeños, pero no tienes una correlación directa de que, oh, tengo que eliminar esto.

Por supuesto, hay herramientas que te ayudan con eso, pero fundamentalmente, cuando estás pensando en hacer el cambio, no tienes que pensar dónde más se usa esta cosa o algo así. Tienes abstracción innecesaria, como mencioné con el ejemplo anterior, como la cosa de la API. Si tienes una excepción única a un tipo de diseño o arquitectura, entonces es mejor convertirla en una excepción que cambiar la abstracción para admitir esa excepción. Finalmente, la propagación de cambios, lo que significa que una vez que haces un cambio en un archivo, ¿cuántos archivos realmente dependen de eso o cuántos lugares, ya sabes, si tienes un fragmento de code que es reutilizable y tienes que cambiarlo, entonces ¿estás seguro de que en todos los lugares donde se usa esa cosa, no estás introduciendo algún error o algún problema, además del hecho de que tienes que pasar por un par de archivos o un conjunto de archivos para hacer un solo cambio en el code? Entonces, estás balanceando este deslizador cada vez que tienes que pensar en la reusabilidad, ¿verdad? ¿Cuánto quieres reutilizar? ¿Cuánto quieres duplicar? Me resulta útil tener tu propio framework para esto y pensarlo como, ok, ¿debería reutilizar esta cosa? Solo un par de preguntas que me gusta hacer sobre esto. ¿Estas cosas cambiarán juntas? ¿Significa que si el componente principal cambia, tengo que ir al componente hijo también y hacer un cambio? ¿O si el componente cambia, el utilitario que calcula algo también tiene que cambiar? Porque si cambian juntos, es mejor que estén juntos que tener algún tipo de reusabilidad o abstracción allí. Entonces, si decides abstraer algo, ¿con qué frecuencia cambias ese code reutilizable? Pensando en la propagación de cambios, ¿verdad? En el momento en que alguna pieza de code que es reutilizable necesita cambiar, hay una mayor probabilidad de que introduzcas algún tipo de error o regresión debido a la cantidad de lugares donde se usa esa cosa. Y finalmente, es muy importante para la fase de lectura, ¿necesitas entender el code que se reutiliza? Entonces, escribes el code, extraes algo en la utilidad, ¿el nombre de la utilidad te brinda suficiente información para que cuando alguien más entre y lea el code, o tú vengas después de un tiempo y leas el code, ¿sabes qué hay allí o tienes que abrirlo realmente para entender qué está sucediendo? Ok. Creo que esto se está quedando sin batería. Lección número cuatro, tal vez estoy un poco retrasado en el tiempo, pero veamos.

5. Dejar Rastros y Legibilidad del Código

Short description:

Dejar rastros en el código es importante para una mejor comprensión. Los comentarios son una forma útil de dejar rastros y proporcionar explicaciones para código crítico o sensible. Descomponer algoritmos complejos en pasos más pequeños y elevar condicionales también puede mejorar la legibilidad del código.

Podemos lograrlo. Lección número cuatro, hablando de comprensión de ese code, es dejar rastros. Esto es muy interesante. Realmente me gusta pensar más en esto. ¿Cómo lo manejas a lo largo del tiempo? ¿Alguna vez has pasado por un fragmento de code preguntándote qué diablos hay aquí? No sé quién escribió esto. Y luego usas GitLens, y dice, eres tú, hace 14 meses. Esto es muy común, y por qué sucede esto es, nuevamente, pensando en esa fase de lectura del code, ¿verdad? Cuando escribes el code, lo escribes en un cierto momento del tiempo, tres meses después, alguien más viene y lee el code, juro por Dios, no sé qué es esta barra de desplazamiento. Es algo del navegador. Tres meses después, vuelves y lees el mismo code. ¿Adivina qué? Tú de hace seis meses no eres el mismo que tú hoy. Estás viendo el code tal vez con nuevos ojos. Simplemente olvidaste algunos detalles de implementación. Es muy importante dejar estos rastros para ti y para tus colegas.

Los rastros más obvios que puedes dejar son los comentarios. A todos les gustan los comentarios, con suerte. No consideras que el code sea autoexplicativo. Tenemos code que es muy crítico o sensible, ¿verdad? Por ejemplo, como un code de ramificación en una fase de carga, ¿verdad? Esta es, por ejemplo, la parte crítica de cargar el proyecto en nuestro editor, ¿verdad? Nuevamente, todos los fragmentos de code son de producción, así que sí. Escribimos un montón de comentarios porque sabemos que cualquier cambio aquí es muy difícil de probar primero porque hay mucha lógica involucrada. ¿Eres un usuario anónimo? ¿Tienes permisos? ¿Estás en un espacio de trabajo? ¿Estás mirando lo correcto? ¿Estás mirando el paso de todos los parámetros y así sucesivamente? Hay un montón de posibilidades. Comentamos mucho en este tipo de code. Con los comentarios, por supuesto, dejas los rastros también para tu futuro.

Lo siguiente es descomponer algoritmos más complejos en pasos más pequeños. Esto va un poco en contra de lo que hablamos, pero en algunos casos, quieres extraer algo así. Por ejemplo, eliminar panel del diseño es una función que tenemos cuando eliminas la última pestaña de un panel, ¿verdad, en un diseño de pestañas? Esto se hace en dos pasos. Primero, eliminas el panel del grupo y si ese grupo no tiene más paneles, entonces también debe ser eliminado. El algoritmo se descompone. Cuando vuelves y lees esto, sabes exactamente qué hace el code porque tienes como las instrucciones, como el algoritmo de nivel superior aquí.

Finalmente, mi cosa favorita que he estado haciendo últimamente es lo que llamo elevar condicionales. Siempre que tengas todas esas cosas donde dices, oh, si algo dot length es mayor que tres, sea lo que sea tres, encuentro muy útil elevar siempre esa lógica en algunas variables con nombres claros en la parte superior de los componentes.

6. Strict Null Checks and Code Reliability

Short description:

Dejar rastros, comentarios, descomponer algoritmos y elevar valores para ayudarte a ti y a los demás a comprender mejor el código en el futuro. La lección número tres es mejor ser estricto que lamentarse. Es importante utilizar las comprobaciones estrictas de nulos de TypeScript para definir explícitamente los posibles valores de las variables y evitar errores en tiempo de ejecución. Al escribir los valores de retorno de los hooks, puedes asegurarte de que el código se comporte como se espera y evitar problemas como pantallas parpadeantes y comprobaciones de nulos.

Realmente abusamos de esto. ¿El equipo de administración debería aplicar límites de sandbox? Incluso si es un booleano de 50 caracteres, sigue siendo mejor porque te explica más adelante cuando leas ese code por qué se aplica esa condición allí, por qué ese code está condicionado por esta cosa. Imagina tener que duplicar todas las lógicas y todos los booleanos en todas las representaciones.

En resumen, dejar rastros, comentarios, descomponer algoritmos y elevar los valores para ayudarte a ti y a los demás a comprender mejor el code en el futuro.

Ahora, la lección número tres es mejor ser estricto que lamentarse. Entonces, ¿alguien puede decirme cuáles son los posibles valores de is pro aquí? ¿Cómo se ve? ¿Es un booleano? ¿Sí? De acuerdo. Bien. Gracias. Lo arruinaste. Sí. Es un booleano. Técnicamente, lo miras y dices, por supuesto, es un booleano, es pro. Entonces, lo que haces es decir, oh, si el usuario no es pro, muestra un banner de actualización. Veamos qué sucede. Por un segundo, el banner se muestra y luego desaparece, y eso es porque is pro debe ser probado exactamente por su valor, que solo cuando is pro es falso explícitamente solo entonces el banner debería mostrarse.

El problema es que is pro es un booleano o indefinido y el problema subyacente es que a veces ni siquiera puedes ver esto a menos que uses el patrocinador de nuestra charla. Lo siento. Estoy bromeando. A menos que uses TypeScript. Porque TypeScript te da el poder de decir explícitamente, hey, esto es un booleano o un indefinido. Y lo llevaría un paso más allá, sí, lo siento. Me olvidé de esto. Esto es muy importante. TypeScript incluso no te dice que es un booleano o indefinido a menos que uses comprobaciones estrictas de nulos. ¿Alguien usa comprobación estricta de nulos en su base de código? De acuerdo. Es algo así, mitad y mitad. Es un poco difícil ponerlo una vez que no lo tienes desde el principio, pero es realmente importante poder expresar la totalidad de los valores, ¿verdad? Y vamos un paso más allá y decimos, okay, el tipo de retorno de un hook es explícitamente así. Es o bien sin data todavía y luego tipas estrictamente todo como indefinido, ¿verdad? O no tiene un objeto de suscripción y luego incluso lo tipas como el valor real que esperas y luego lo tipas con lo que normalmente pondrías, como el tipo regular allí en la parte inferior. Y esto es súper útil, nuevamente, porque evitas cualquiera de estos problemas donde, ya sabes, tienes parpadeos en la pantalla, comprobaciones de indefinidos, nulos y todo eso, y por supuesto posibles errores en tiempo de ejecución si no usas una comprobación estricta de nulos. Entonces, finalmente, el code debería verse así, donde incluso pruebas is pro solo para asegurarte de que estás testing todas las excepciones.

7. Conclusion and Recap

Short description:

Utiliza TypeScript lo más estricto posible. Tipifica explícitamente todos los estados de tus datos. Maneja todos los posibles estados para evitar errores en el futuro. Acepta la imperfección. La colocación es fundamental. La reutilización es una espada de doble filo. Deja rastros y mejor ser estricto que lamentarse. Estas fueron mis cinco lecciones para construir bases de código resilientes.

Y luego, después de la línea, no tiene un número allí, pero después de la primera condicional, básicamente, este pro va a ser exactamente lo que esperas, verdadero o falso, porque probaste el valor atípico, que es, nuevamente, indefinido, pero tiene sentido porque es indefinido mientras se está obteniendo data en la fase inicial. De acuerdo. Entonces, para concluir mejor, ser estricto que lamentarse, utiliza TypeScript lo más estricto posible. Tipifica explícitamente todos los estados de tus data. No olvides cuándo debería ser nulo, cuándo debería ser indefinido. Maneja todos estos posibles estados porque esto te ahorrará un montón de errores en el futuro y comportamientos extraños en la aplicación.

Un resumen rápido a lo largo del tiempo. Acepta la imperfección. La colocación es fundamental. La reutilización es una espada de doble filo. Deja rastros y mejor ser estricto que lamentarse.

8. Architecture and Guidelines

Short description:

Estas fueron mis cinco lecciones para construir bases de código resilientes. Gracias por unirse. Mantener los componentes en archivos separados pero en la misma carpeta puede funcionar, pero puede dificultar la navegación entre archivos. Depende de tu habilidad con el editor de código. El uso de carpetas también puede ser beneficioso, pero ten cuidado con los archivos de índice que pueden complicar la estructura del proyecto. Cuando se trata de tener múltiples funciones en un archivo, si los componentes más pequeños deben ser probados individualmente, deben ser extraídos. De lo contrario, el enfoque de las pruebas debe estar en el componente principal. Una arquitectura imperfecta puede ser manejada por desarrolladores experimentados que saben cuándo hacer excepciones. Las pautas de ingeniería pueden ayudar a los equipos junior o menos disciplinados a entender las reglas básicas. Se pueden hacer excepciones, pero deben ser revisadas cuidadosamente para mantener la escalabilidad de la base de código. Las pautas juegan un papel crucial en mantener una arquitectura consistente y escalable.

Estas fueron mis cinco lecciones para construir bases de código resilientes. Gracias por unirse.

Vamos a ver, ¿cuál queremos hacer primero? Muy bien, aquí. Mostraste un ejemplo con múltiples componentes en un archivo. ¿Qué opinas de mantenerlos en archivos separados pero en la misma carpeta? Eso también funciona. Mi problema con eso es que a veces es difícil saltar entre archivos. También depende de cuán hábil seas con el editor de código. He encontrado que a veces para algunas personas es fácil visualizar la descomposición de un componente principal en un solo archivo, pero eso también funciona con carpetas. El problema con las carpetas es que te invita a usar cosas como archivos de índice que a veces son la raíz de todos los problemas en las estructuras del proyecto, así que hay que tener cuidado con eso.

Mucha gente tiene preguntas sobre mantener múltiples funciones en un archivo. ¿A dónde se fue? Tenía una muy buena. Muy bien, aquí. Cuando se tienen varios componentes en un archivo, ¿cómo abordarías la estructura de pruebas de ese archivo? Esa es una buena pregunta. Creo que si los componentes necesitan ser probados, si los componentes más pequeños necesitan ser probados por alguna razón, entonces probablemente deberían ser extraídos. Pero si son simplemente una descomposición del componente principal, entonces la prueba debería ser alrededor del componente principal. Debería ser más una prueba de alto nivel que una prueba de unidad separada para cada fragmento que tengas allí.

Muy bien, gracias. Así que una arquitectura imperfecta y estar cómodo con eso parece depender de los desarrolladores experimentados. Pero si tienes un equipo lleno de personas junior o menos disciplinadas, ¿no sería eso una receta para el desastre? Sí y no. Importa mucho tener la experiencia para saber cuándo algo debería ser una excepción y cuándo no. Creo que tener algunas pautas de ingeniería para el equipo siempre ayuda. Siempre ha ayudado en mi experiencia. Ser capaz de decir, okay, siempre lo hacemos así, ¿verdad? Por ejemplo, solo tenemos un componente exportado desde un archivo. Eso debería ser una regla básica, ¿verdad? Ya sea que sean junior o senior, deberían poder leer nuestras pautas de ingeniería y decir, okay, estas son las reglas, las reglas básicas. A partir de aquí, experimentamos y si encontramos algo, por ejemplo, encuentras en una revisión de código, alguien junior, digamos, hace algo y dices, oh, espera, esto es una excepción, pero es un poco demasiado para tolerar. Eso está bien. La persona senior, tal vez, para revisarlo y decir, okay, no hagamos esto y tal vez incluso escribirlo en nuestras pautas de ingeniería que no deberíamos hacer esto para escalar adecuadamente la base de código.

Sí, y mencionaste las pautas. Quiero profundizar en eso con esta pregunta.

9. Convenciones de Nomenclatura y Control de Versiones

Short description:

Las convenciones de nomenclatura adecuadas son esenciales para la legibilidad del código. Tener más ojos en el código y sugerir mejores nombres en las PR puede mejorar la comprensión. Cuando se tienen múltiples componentes en un archivo, la complejidad del control de versiones y los conflictos de fusión no son significativamente diferentes de tenerlos en archivos separados. Sin embargo, se vuelve más complicado cuando los cambios abarcan varios archivos. Los comentarios deben tratarse como parte del código y actualizarse durante las PR para evitar conocimientos obsoletos.

¿Qué hay de las convenciones de nomenclatura adecuadas? ¿Ayudaría eso también? Sí, siempre ayuda. Creo que ser... Aunque suene tonto, muchos de los comentarios en las PR que he visto en proyectos múltiples son del tipo: `¿No deberíamos nombrar esto mejor así?` Porque nombrar las cosas es difícil. Por muy buenos que creamos ser en nombrar las cosas, tener más personas que revisen un booleano, una función, un componente y que alguien diga: `Sí, esto está bien, pero ¿por qué no lo nombramos así?` En mi modelo mental, suena como si lo reconociera mejor en el futuro. Así que siempre hay que tener convenciones de nomenclatura, pero nunca hay que tener miedo de sugerir en las PR, supongo, mejores nombres si encontramos que algo se entiende mejor de esta manera. Sí. Gracias. Cuando tienes múltiples componentes en un archivo, nos enfrentamos a ese problema. ¿No será más complejo el control de versiones y acabará causando conflictos de fusión desagradables? Bueno, tal vez la idea de tener múltiples componentes, tal vez la gente piense que todos esos componentes son como hermanos, pero nuevamente, esto es más como una relación padre-hijo. No es... La mayoría de las veces, no estarás... Quiero decir, digamos que llegas a ese ejemplo con los planes de precios. Digamos que tienes que cambiar, tienes que introducir una nueva línea para cada tarjeta. Eso probablemente significaría que tienes que hacer cambios en tres componentes, tal vez. Ya sea que estén en tres archivos o en solo tres líneas diferentes en el mismo archivo, la diferencia en el git diff será la misma, ¿verdad? No creo que haya una gran diferencia entre los dos. De hecho, si una parte de ese archivo cambia... Quiero decir, básicamente, cuando tienes que cambiar fundamentalmente... O no fundamentalmente. Cuando tienes que cambiar ligeramente algo en uno de esos archivos, está bien que afecte a todos los componentes en ese archivo. Si afectara a varios archivos, entonces en mi opinión, se vuelve un poco más complicado manejar todas las versiones y todos los posibles conflictos con otros cambios realizados por otras personas y en diferentes archivos. De acuerdo. Muchas gracias. Tal vez una última pregunta rápida. Mencionaste que los comentarios son geniales, pero a medida que el code evoluciona, ¿no conducirá a conocimientos obsoletos? ¿Existen mejores soluciones? No encontré una mejor... Siempre es un problema. Estoy de acuerdo. Hay que tener mucho cuidado de no dejar comentarios obsoletos. Los comentarios deben tratarse como parte del code. Y nuevamente, utiliza las PR para decir... Oye, si has realizado este cambio, has cambiado el límite de algo, actualiza el comentario para reflejar eso o algo así. No creo que puedas... Quiero decir, probablemente podrías automatizar eso en el futuro con, no sé, con IA o algo así, pero por ahora, creo que estamos atrapados con lo que tenemos. De acuerdo. Démonos un último aplauso para Alex. Muchas gracias. Gracias.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Depuración de JS
React Summit 2023React Summit 2023
24 min
Depuración de JS
Top Content
Debugging JavaScript is a crucial skill that is often overlooked in the industry. It is important to understand the problem, reproduce the issue, and identify the root cause. Having a variety of debugging tools and techniques, such as console methods and graphical debuggers, is beneficial. Replay is a time-traveling debugger for JavaScript that allows users to record and inspect bugs. It works with Redux, plain React, and even minified code with the help of source maps.
Un Marco para Gestionar la Deuda Técnica
TechLead Conference 2023TechLead Conference 2023
35 min
Un Marco para Gestionar la Deuda Técnica
Top ContentPremium
Today's Talk discusses the importance of managing technical debt through refactoring practices, prioritization, and planning. Successful refactoring requires establishing guidelines, maintaining an inventory, and implementing a process. Celebrating success and ensuring resilience are key to building a strong refactoring culture. Visibility, support, and transparent communication are crucial for addressing technical debt effectively. The team's responsibilities, operating style, and availability should be transparent to product managers.
Construyendo un Asistente AI Activado por Voz con Javascript
JSNation 2023JSNation 2023
21 min
Construyendo un Asistente AI Activado por Voz con Javascript
Top Content
This Talk discusses building a voice-activated AI assistant using web APIs and JavaScript. It covers using the Web Speech API for speech recognition and the speech synthesis API for text to speech. The speaker demonstrates how to communicate with the Open AI API and handle the response. The Talk also explores enabling speech recognition and addressing the user. The speaker concludes by mentioning the possibility of creating a product out of the project and using Tauri for native desktop-like experiences.
Una Guía Práctica para Migrar a Componentes de Servidor
React Advanced 2023React Advanced 2023
28 min
Una Guía Práctica para Migrar a Componentes de Servidor
Top Content
React query version five is live and we'll be discussing the migration process to server components using Next.js and React Query. The process involves planning, preparing, and setting up server components, migrating pages, adding layouts, and moving components to the server. We'll also explore the benefits of server components such as reducing JavaScript shipping, enabling powerful caching, and leveraging the features of the app router. Additionally, we'll cover topics like handling authentication, rendering in server components, and the impact on server load and costs.
Solucionando Problemas de Rendimiento en React
React Advanced 2023React Advanced 2023
22 min
Solucionando Problemas de Rendimiento en React
Top Content
This Talk discusses various strategies to improve React performance, including lazy loading iframes, analyzing and optimizing bundles, fixing barrel exports and tree shaking, removing dead code, and caching expensive computations. The speaker shares their experience in identifying and addressing performance issues in a real-world application. They also highlight the importance of regularly auditing webpack and bundle analyzers, using tools like Knip to find unused code, and contributing improvements to open source libraries.
De Monolito a Micro-Frontends
React Advanced 2022React Advanced 2022
22 min
De Monolito a Micro-Frontends
Top Content
Microfrontends are considered as a solution to the problems of exponential growth, code duplication, and unclear ownership in older applications. Transitioning from a monolith to microfrontends involves decoupling the system and exploring options like a modular monolith. Microfrontends enable independent deployments and runtime composition, but there is a discussion about the alternative of keeping an integrated application composed at runtime. Choosing a composition model and a router are crucial decisions in the technical plan. The Strangler pattern and the reverse Strangler pattern are used to gradually replace parts of the monolith with the new application.

Workshops on related topic

Construyendo una Aplicación de Shopify con React & Node
React Summit Remote Edition 2021React Summit Remote Edition 2021
87 min
Construyendo una Aplicación de Shopify con React & Node
Top Content
Workshop
Jennifer Gray
Hanna Chen
2 authors
Los comerciantes de Shopify tienen un conjunto diverso de necesidades, y los desarrolladores tienen una oportunidad única para satisfacer esas necesidades construyendo aplicaciones. Construir una aplicación puede ser un trabajo duro, pero Shopify ha creado un conjunto de herramientas y recursos para ayudarte a construir una experiencia de aplicación sin problemas lo más rápido posible. Obtén experiencia práctica construyendo una aplicación integrada de Shopify utilizando el CLI de la aplicación Shopify, Polaris y Shopify App Bridge.Te mostraremos cómo crear una aplicación que acceda a la información de una tienda de desarrollo y pueda ejecutarse en tu entorno local.
Construye una sala de chat con Appwrite y React
JSNation 2022JSNation 2022
41 min
Construye una sala de chat con Appwrite y React
Workshop
Wess Cope
Wess Cope
Las API/Backends son difíciles y necesitamos websockets. Utilizarás VS Code como tu editor, Parcel.js, Chakra-ui, React, React Icons y Appwrite. Al final de este masterclass, tendrás los conocimientos para construir una aplicación en tiempo real utilizando Appwrite y sin necesidad de desarrollar una API. ¡Sigue los pasos y tendrás una increíble aplicación de chat para presumir!
Problemas difíciles de GraphQL en Shopify
GraphQL Galaxy 2021GraphQL Galaxy 2021
164 min
Problemas difíciles de GraphQL en Shopify
Workshop
Rebecca Friedman
Jonathan Baker
Alex Ackerman
Théo Ben Hassen
 Greg MacWilliam
5 authors
En Shopify a gran escala, resolvemos algunos problemas bastante difíciles. En este masterclass, cinco oradores diferentes describirán algunos de los desafíos que hemos enfrentado y cómo los hemos superado.

Tabla de contenidos:
1 - El infame problema "N+1": Jonathan Baker - Vamos a hablar sobre qué es, por qué es un problema y cómo Shopify lo maneja a gran escala en varios APIs de GraphQL.
2 - Contextualizando APIs de GraphQL: Alex Ackerman - Cómo y por qué decidimos usar directivas. Compartiré qué son las directivas, qué directivas están disponibles de forma predeterminada y cómo crear directivas personalizadas.
3 - Consultas de GraphQL más rápidas para clientes móviles: Theo Ben Hassen - A medida que tu aplicación móvil crece, también lo harán tus consultas de GraphQL. En esta charla, repasaré diversas estrategias para hacer que tus consultas sean más rápidas y efectivas.
4 - Construyendo el producto del futuro hoy: Greg MacWilliam - Cómo Shopify adopta las características futuras en el código actual.
5 - Gestión efectiva de APIs grandes: Rebecca Friedman - Tenemos miles de desarrolladores en Shopify. Veamos cómo estamos asegurando la calidad y consistencia de nuestras APIs de GraphQL con tantos colaboradores.
Construye Aplicaciones Modernas Utilizando GraphQL y Javascript
Node Congress 2024Node Congress 2024
152 min
Construye Aplicaciones Modernas Utilizando GraphQL y Javascript
Workshop
Emanuel Scirlet
Miguel Henriques
2 authors
Ven y aprende cómo puedes potenciar tus aplicaciones modernas y seguras utilizando GraphQL y Javascript. En este masterclass construiremos una API de GraphQL y demostraremos los beneficios del lenguaje de consulta para APIs y los casos de uso para los que es adecuado. Se requiere conocimiento básico de Javascript.
De 0 a Autenticación en una Hora para tu Aplicación JavaScript
JSNation 2023JSNation 2023
57 min
De 0 a Autenticación en una Hora para tu Aplicación JavaScript
WorkshopFree
Asaf Shen
Asaf Shen
La autenticación sin contraseña puede parecer compleja, pero es fácil de agregar a cualquier aplicación utilizando la herramienta adecuada.
Mejoraremos una aplicación JS de pila completa (backend Node.js + frontend Vanilla JS) para autenticar usuarios con contraseñas de un solo uso (correo electrónico) y OAuth, incluyendo:
- Autenticación de usuario: Gestión de interacciones de usuario, devolución de JWT de sesión / actualización- Gestión y validación de sesiones: Almacenamiento seguro de la sesión para solicitudes posteriores del cliente, validación / actualización de sesiones
Al final del masterclass, también abordaremos otro enfoque para la autenticación de código utilizando Flujos de Descope en el frontend (flujos de arrastrar y soltar), manteniendo solo la validación de sesión en el backend. Con esto, también mostraremos lo fácil que es habilitar la biometría y otros métodos de autenticación sin contraseña.