Desarrollo de módulos Angular

Intermedio
Angular
Angular
Actualizado: 04/05/2026

Componentes standalone: el estándar en Angular 21

flowchart LR
    LEG["NgModule (legacy): @NgModule, declarations"] -.->|migración| STD["Standalone: imports en cada componente"]
    STD --> APP["app.config.ts: providers globales"]
    APP --> BOOT["bootstrapApplication(AppComponent)"]
    STD --> LAZY["loadComponent: carga diferida sin módulo"]
    STD --> MIG["ng generate @angular/core:standalone-migration"]
    LEG --> NGM["@NgModule + declarations + exports"]
    NGM --> SHARED["Útil para mantener proyectos existentes"]

A partir de Angular 17, y consolidado completamente en Angular 21, los componentes standalone son el enfoque estándar para organizar aplicaciones Angular. Los componentes standalone no necesitan ser declarados en un módulo y pueden importar directamente las dependencias que necesitan.

Arquitectura moderna sin NgModule

En Angular 21, al crear un proyecto con ng new, la aplicación se configura directamente con componentes standalone y un archivo app.config.ts que centraliza la configuración:

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    // otros providers...
  ]
};
// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';

bootstrapApplication(AppComponent, appConfig)
  .catch(err => console.error(err));

Los componentes importan directamente lo que necesitan:

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet],
  template: `
    <h1>Mi aplicación Angular 21</h1>
    <router-outlet />
  `
})
export class AppComponent { }

Ventajas de los componentes standalone

Los componentes standalone ofrecen varias ventajas sobre el enfoque basado en NgModule:

1. Simplicidad: Cada componente declara explícitamente sus dependencias, eliminando la necesidad de módulos intermedios.

2. Mejor tree-shaking: El compilador puede eliminar código no utilizado de forma más eficiente.

3. Menor boilerplate: No es necesario crear ni mantener archivos de módulo adicionales.

4. Carga lazy más directa: Se pueden cargar componentes individuales de forma diferida sin necesidad de un módulo envoltorio.

// app.routes.ts - Lazy loading directo de componentes standalone
const routes: Routes = [
  { 
    path: 'tasks', 
    loadComponent: () => import('./task/task-list.component')
      .then(m => m.TaskListComponent) 
  },
  { 
    path: 'users', 
    loadComponent: () => import('./user/user-list.component')
      .then(m => m.UserListComponent) 
  }
];

NgModule: el enfoque clásico (legacy)

Los módulos (NgModule) fueron el componente fundamental en la arquitectura de Angular desde Angular 2 hasta Angular 16, actuando como contenedores que agrupaban componentes, directivas, pipes y servicios relacionados para formar unidades funcionales cohesivas.

Importante: En Angular 21, los NgModules se consideran un enfoque legacy. Se mantienen por compatibilidad con proyectos existentes, pero no se recomienda su uso en nuevos proyectos. Es probable que los encuentres al trabajar con código base antiguo o librerías que aún no se han migrado a standalone.

Importancia histórica de los módulos

Los módulos fueron fundamentales en Angular por varias razones:

1. Organización del código: Permitían una mejor estructuración y organización del código fuente.

2. Reutilización: Facilitaban la reutilización de componentes y servicios en diferentes partes de una aplicación.

3. Lazy loading: Posibilitaban la carga diferida de partes de una aplicación para mejorar el rendimiento.

4. Encapsulación: Ayudaban a encapsular características y funcionalidades en bloques de código independientes.

5. Optimización de compilación: Permitían una compilación más eficiente mediante la agrupación lógica de componentes.

Creación de módulos

Para crear un módulo en Angular, se utiliza el comando de Angular CLI:

ng generate module MiModulo

Nota: En Angular 21, este comando sigue disponible por compatibilidad, pero para nuevos proyectos se recomienda crear componentes standalone directamente con ng generate component.

Estructura de un módulo

Un módulo en Angular se define mediante el decorador @NgModule. Este decorador acepta un objeto de metadatos que describe cómo se debe compilar el módulo y qué elementos incluye.

Ejemplo de un módulo básico:

// task.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TaskListComponent } from './task-list/task-list.component';
import { TaskDetailComponent } from './task-detail/task-detail.component';
import { TaskService } from './task.service';

@NgModule({
  declarations: [
    TaskListComponent,
    TaskDetailComponent
  ],
  imports: [
    CommonModule
  ],
  exports: [
  TaskListComponent
  ],
  providers: [
    TaskService
  ]
})
export class TaskModule { }

En este ejemplo, TaskModule agrupa los componentes TaskListComponent y TaskDetailComponent, así como el servicio TaskService. El módulo también importa el módulo CommonModule, que proporciona directivas y funcionalidades comunes.

Secciones de un módulo

Un módulo típicamente contiene las siguientes secciones:

1. Declarations: Lista de componentes, directivas y pipes pertenecientes al módulo.

2. Imports: Otros módulos cuyas exportaciones son necesarias para los componentes de este módulo.

3. Exports: Componentes, directivas y pipes que deben estar disponibles para otros módulos.

4. Providers: Servicios que el módulo contribuye a la colección global de servicios.

Ejemplo de módulo con secciones

// feature.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FeatureComponent } from './feature.component';
import { FeatureService } from './feature.service';

@NgModule({
  declarations: [FeatureComponent],
  imports: [CommonModule],
  providers: [FeatureService],
  exports: [FeatureComponent]
})
export class FeatureModule { }

Módulo raíz (AppModule) - Angular 16 y anteriores

El módulo principal de una aplicación Angular se conocía como AppModule. Este módulo se creaba automáticamente al iniciar un nuevo proyecto en versiones de Angular 16 y anteriores, y era responsable de arrancar la aplicación.

Ejemplo de AppModule:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { TaskModule } from './task/task.module';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    TaskModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

En este ejemplo, AppModule importa tanto el módulo BrowserModule como el módulo personalizado TaskModule. También define el componente raíz AppComponent y establece que este componente se utilizará como punto de inicio para la aplicación.

En Angular 17+ y especialmente en Angular 21, este archivo AppModule ya no se genera por defecto. En su lugar, la aplicación se arranca con bootstrapApplication() y un archivo app.config.ts, como se mostró en la sección anterior.

Importación y exportación de módulos

Los módulos pueden importar funcionalidades de otros módulos y también pueden exportar funcionalidades a otros módulos.

Ejemplo de importación y exportación

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FeatureModule } from './feature/feature.module'; // Importación del módulo
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    FeatureModule // Uso del módulo importado
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Lazy Loading con NgModule vs. Standalone

Angular permite configurar lazy loading tanto con módulos como con componentes standalone.

Enfoque clásico con NgModule:

// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: 'tasks', loadChildren: () => import('./task/task.module').then(m => m.TaskModule) },
  { path: 'users', loadChildren: () => import('./user/user.module').then(m => m.UserModule) }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Enfoque moderno con componentes standalone (recomendado en Angular 21):

// app.routes.ts
import { Routes } from '@angular/router';

export const routes: Routes = [
  { 
    path: 'tasks', 
    loadComponent: () => import('./task/task-list.component')
      .then(m => m.TaskListComponent) 
  },
  { 
    path: 'users', 
    loadComponent: () => import('./user/user-list.component')
      .then(m => m.UserListComponent) 
  }
];

El enfoque con loadComponent es más directo y no requiere crear un módulo wrapper para cada funcionalidad que se quiera cargar de forma diferida.

Migración de NgModule a Standalone

Si trabajas con un proyecto legacy que utiliza NgModule y deseas migrar a componentes standalone, Angular CLI proporciona un schematic de migración automática:

ng generate @angular/core:standalone

Este comando automatiza gran parte del proceso de migración, convirtiendo componentes, directivas y pipes declarados en módulos a componentes standalone equivalentes. El proceso se realiza en tres pasos:

  1. Convertir componentes a standalone: Añade standalone: true y mueve las importaciones necesarias al componente.
  2. Eliminar NgModules innecesarios: Elimina los módulos que ya no contienen declaraciones.
  3. Actualizar bootstrap: Reemplaza el arranque basado en AppModule por bootstrapApplication.

Para proyectos nuevos en Angular 21, se recomienda comenzar directamente con componentes standalone y utilizar app.config.ts para la configuración de la aplicación, evitando por completo el uso de NgModule.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Angular es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Angular

Explora más contenido relacionado con Angular y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender la evolución de NgModule hacia componentes standalone en Angular
  • Conocer la estructura y secciones de un NgModule para proyectos legacy.
  • Aprender a importar y exportar módulos en aplicaciones que los utilicen.
  • Entender cuándo se pueden encontrar NgModules en proyectos existentes y cómo migrar a standalone.