Mejor estructura de código: trabajando con pods
Normalmente organizamos nuestras apps de javascript o bien por lo que son o bien por lo que hacen. La primera es como rails: directorios separados como components, containers, reducers, etc. Y la segunda más o menos como feature/DDD: user, cart, etc. Aunque ambas opciones son muy mainstream y sólidas, contienen algunas limitaciones. Cuando estructuras el código…
Normalmente organizamos nuestras apps de javascript o bien por lo que son o bien por lo que hacen. La primera es como rails: directorios separados como components, containers, reducers, etc. Y la segunda más o menos como feature/DDD: user, cart, etc. Aunque ambas opciones son muy mainstream y sólidas, contienen algunas limitaciones.
Cuando estructuras el árbol de archivos del código por lo que son, tiendes a mantener cada componente de la misma feature tan distante que resulta muy difícil conectar las piezas. Por eso te metes en algunos problemas como el infierno de las rutas; un montón de require('../../../etc') en tu código. Y todo queda extremadamente acoplado a la estructura de directorios.
Por otro lado, cuando te guías por lo que hacen, todo está más aislado y es más mantenible. Pero hay mucha duplicación. Y la comunicación entre las features o bien se basa en un contrato débil o bien depende de alguna infraestructura. Ambas opciones son propensas a generar algunos bugs.
Pods es una evolución de la última. Puedes pensar en los pods como los microservicios de las aplicaciones front. Un pod es una microapp aislada y completamente independiente que puede comunicarse al 100% con otros pods. Por lo tanto, obtienes una base de código que es composable, extensible, reutilizable y extremadamente fácil de testear. Aunque el principal beneficio es que eliminas por completo los efectos secundarios entre componentes. Una vez que un pod falla, tienes la total seguridad de que es porque él mismo tiene algo mal; no una pieza externa.
Un pod es una microapp aislada y completamente independiente que puede comunicarse al 100% con otros pods
El único requisito de los pods es dirigir toda la intercomunicación entre pods a través de un event bus. Si ya estás usando algún patrón, librería o framework de Flux, va a ser muy fácil llevar esta comunicación al dispatcher; que en realidad es un punto único para los eventos.
Para un pod no es obligatorio tener las capas de lógica, presentación y comunicación. Puede tener solo una de ellas. Imagina un pod de router. Tiene la capa de lógica y comunicación pero no expone ninguna vista. O al contrario, un pod de formulario que solo expone una capa de presentación y depende al 100% de los argumentos recibidos (mira los props de React).
Como cada pod actúa como una aplicación independiente, colocamos los tests dentro de ellos. Esto significa dos cosas: dejar de duplicar el árbol de archivos y hacer que la cobertura de código sea significativa. Cuando tienes un 100% de cobertura en un pod, sabes que no va a fallar. Sin efectos secundarios.
En resumen, trabajando con pods obtienes una estructura segura y muy flexible. Muy fácil de testear y sin efectos secundarios. Escala de 0 a millones sin preocuparte por grandes refactors debido a que cada pod está aislado pero disponible para comunicarse con todos los demás pods.
En caso de que quieras ver algo de código, aquí tienes un repositorio de Github con una arquitectura de pods sencilla. Échale un vistazo y comprueba los beneficios que pueden ofrecer los pods. Si tienes alguna duda o propuesta no dudes en abrir un issue o comentar aquí. Este es un patrón vivo. Estamos usando los pods en Ulabox y están demostrando ser la solución a muchos problemas estructurales de la base de código. Aunque estamos dispuestos a escuchar tus opiniones y preocupaciones.
El viaje es largo, coge algunos pods.