Angular 9: Estructura de carpetas para una aplicación escalable.

¿Cómo definir una estructura de carpetas para crear aplicaciones angular escalables y mantenibles aplicando los patrones; LIFT (Locate, Identify, Flat and Try DRY), Smart and Dumb components y Redux?

Organización general del proyecto

En la siguiente arquitectura nos enfocamos en una aplicación escalable a nivel de arquitectura y datos en el frontend.

Se maneja una escalabilidad desde las buenas prácticas que angular propone para mantener el código, la arquitectura y organización de las carpetas. Se maneja una arquitectura escalable a nivel de datos que hace que sea eficiente saber qué pasa a nivel de toda la aplicación utilizando el patrón Redux.

Redux como patrón de datos resuelve toda la arquitectura y manejo de datos en un solo sentido. Lo que hacemos con redux es manejar un solo flujo de información donde uno de sus principios es que tiene una sola fuente de la verdad la cual llama storage, donde siempre va a estar disponible la data, permitiendo obtener un mayor control sobre el flujo de datos y el estado de la aplicación con un estado global inmutable.

El proyecto sigue de cerca la estructura de Folders by features (carpetas por característica de la aplicación) de la guía de estilo angular, lo que permite a su vez el desarrollo de una aplicación modularizada.

Esta estructura, la aplicación tiene cuatro tipos fundamentales de módulos.

  • Root Module
  • Core Module
  • Shared Module
  • Features Module

Veamos la responsabilidad de cada módulo y cómo ayudan a crear una mejor estructura de proyecto.

Root Module

El AppModule es punto de entrada de la aplicación y tiene las siguientes responsabilidades (Por convención y por defecto, este NgModule se llama AppModule):

  • Arranque de la aplicación con el AppComponent.
  • Importa dependencias globales como BrowserModule, CoreModule y LoggerModule.
  • Configura el enrutamiento para toda la aplicación, permitiendo la carga diferida para los módulos de características.

Core Modulo

El Core Module es responsable de mantener los servicios globales. Lo más probable es que estos servicios sean servicios HTTP para comunicarse con una API. También se utiliza para almacenar guards, modelos y otras dependencias globales, como el interceptor http y el controlador de errores global. Para mantener una base de código bien estructurada y escrita, vamos a agrupar entidades typescript en su propia carpeta dentro del core module (clases, enums, interfaces).

El Core Module agrupa “componentes” que si y sólo si se van a compartir a través de toda la aplicación pero generando una referencia única. (Es la única diferencia con el Shared Módulo). El Shared módulo debe ser importado, en cambio el Core Module por defecto va a estar en todos los módulos, sirve para guardar servicios que tengan una sola referencia de los datos.

Shared Module

El Shared Module contiene código que se usará en todos los módulos de features, se utiliza solo para mantener componentes, pipes y directivas comunes en toda la aplicación.

Feature Module

Los módulos de features se utilizan para organizar cada feature distinta de una aplicación. Un Feature Module no exporta nada excepto el componente superior, por lo que todo lo que definimos dentro de él no se utilizará en ningún otro lado.

Siguiendo el patrón Smart and Dumb components, cada módulo debe tener un directorio de components (Contiene componentes Dumb) y un directorio containers (Contiene Smart Components).

Un Dumb Component define un componente que no tiene muchos estados, no tiene acceso a los servicios, no almacena datos en un back-end. Lo que realmente hace es mantener el enfoque del componente en la presentación, encargándose de renderizar las vistas usando inputs y outputs. También podemos llamarlos componentes aislados.

Un Smart Component contiene estados, servicios de implementación o cualquier tipo de lógica de negocios que ocurra en ese componente. No se centra en la presentación, sino en lo que sucede en el componente. Luego, simplemente emite las propiedades a Dumb Component las cuales son recibidas por el decorador @Input. (Se encargan de obtener datos).

Finalmente cada módulo contendrá los directorios y archivos para el manejo de directivas, routing y servicios del mismo.

Otros archivos y directorios importantes:

Routing

AppModule habilita rutas cargadas de manera diferida para presentar módulos (lazy-loading), lo que significa que el módulo no se carga antes de que el usuario acceda a la ruta.

Esto permite que cada módulo de feature tenga su propia configuración de enrutamiento, que mantiene las rutas en los módulos de features correspondientes. (Esto está dentro del Root Module)

Folder Layout

La carpeta de Layout es un contenedor de componentes que se declaran en el AppModule. Este directorio contiene componentes de contenido a nivel de página, como footer, navegación y headers comunes. (Esto está dentro del Root Module)

Folder Styles

El directorio ~/src/styles se utiliza para almacenar hojas de estilo scss para la aplicación. Puede contener temas, Bootstrap, material angular y cualquier otro estilo.

El directorio ~/src/styles/themes debe contener los temas de toda la aplicación. Ejem: Un aplicación puede incluir dos archivos de tema, black-theme.scss y light-theme.scss. (Esto está dentro del Root Module)

Folder Store (Administración del Estado)

El directorio ~/src/store se utiliza para manejar el estado de la aplicación aplicando el patrón redux que actúa como un contenedor del estado global de nuestra aplicación. Almacena toda la información en un sólo lugar, la cual es representada bajo un objeto JavaScript accesible en todo momento.

Es conveniente crear módulos para cada feature de la aplicación en este directorio, en los cuales se crearán las configuraciones de manejo de estado propias del patrón redux (State, Action, Reducer, Effect).

Cada módulo de feature deberá importar su módulo de manejo de estado correspondiente.

Conclusión

Para resumir nuestra estructura de carpetas:

.
├── app.component.html
├── app.component.spec.ts
├── app.component.ts
├── app.module.ts
├── app-routing.module.ts
├── contact
│ ├── components
│ │ ├── contact.component.html
│ │ ├── contact.component.scss
│ │ └── contact.component.ts
│ └── service
│ └── contact.service.ts
├── core
│ ├── core.module.ts
│ ├── http
│ │ └── api-prefix.interceptor.ts
│ └── index.ts
├── global
│ ├── constants.ts
│ ├── endpoints.ts
│ └── global.module.ts
├── shared
│ ├── app-navbar
│ │ ├── app-navbar.component.html
│ │ ├── app-navbar.component.scss
│ │ └── app-navbar.component.ts
│ ├── app-sidemenu
│ ├── index.ts
│ └── shared.module.ts
└── user
├── components
│ ├── user.component.html
│ ├── user.component.scss
│ └── user.component.ts
├── service
│ └── user.service.ts
├── store
│ ├── user.action.ts
│ ├── user.effect.ts
│ ├── user.reducer.ts
│ └── user.state.ts
├── user.module.ts
└── user-routing.module.ts

Es probable que para proyectos pequeños la estructura de carpetas generadas por el Angular CLI sea suficiente (components, services, pipes…), sin embargo, cuando el proyecto se torna grande, la estructura de carpetas debe ser escalable, así evitar desorganización y hacer mas fácil las tareas de incluir y mejorar funcionalidades.

No hay una regla general a la hora de crear una estructura de carpetas en Angular, sobre todo en proyectos grandes. La estructura cambiará mucho según las características del proyecto . La idea general en este artículo es mantener un aplicación ordenada, consistente y que en la medida de lo posible se explique por sí sola.

El código fuente del proyecto se encuentra cargado en github

Finalmente recuerda:

Tener una visión a corto plazo de la implementación y una visión a largo plazo. Comience con poco, pero tenga en cuenta hacia dónde se dirige la aplicación.

Te ha gustado el Post? o crees que hay algo pueda mejorar? no dudes en dejarlo en los comentarios!. Puedes estar en contacto conmigo en mis cuentas de Twitter y LinkedIn.☺

¡Compártelo!

Siéntete libre de compartir 😄 Y recuerda que puedes aplaudir más de una vez!

Referencias:

  1. https://angular.io/guide/styleguide
  2. https://stackoverflow.com/questions/56938106/angular-project-structure-for-enterprise-projects
  3. https://itnext.io/choosing-a-highly-scalable-folder-structure-in-angular-d987de65ec7
  4. https://itnext.io/building-an-enterprise-grade-angular-project-structure-f5be32533ba3
  5. https://angular-folder-structure.readthedocs.io/en/latest/default.html
  6. https://onthecode.co.uk/scalable-angular-project-structure/
  7. https://frontend.consulting/building-an-enterprise-grade-angular-project-structure
  8. https://onthecode.co.uk/scalable-angular-project-structure/#routing
  9. https://medium.com/karibu-blog/estructura-de-carpetas-de-angular-para-la-vida-real-1a8b78bc99b

--

--

--

Mi cuardeno de anotaciones, donde intento compartir experiencias de desarrollo, experimentos e interactuar con la comunidad.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
William Bastidas

William Bastidas

Developer | Web | Mobile | Ionic | TypeScript | JavaScript | Angular | UI | UX | Git | Html | CSS | Agile | Frontend | PWA. Always in Learning mode…

More from Medium

Cell Tower Records and Tarot Cards

CS 373 Spring 2022: Yifan Zhou

CS371p Spring 2022: Max Thomas