Understanding Angular Modules Root, Feature

Angular is a powerful framework for building large-scale, maintainable web applications. One of its core architectural concepts is the module system, which allows developers to organize the application into cohesive blocks of functionality. Modules help improve maintainability, scalability, and code reusability, making Angular applications easier to develop and manage.

In this guide, we will explore:

  1. What are Angular Modules?
  2. Types of Angular Modules
    • Root Module
    • Feature Modules
    • Shared Modules
  3. Organizing large applications using modules
  4. Lazy loading and module optimization
  5. Best practices
  6. Practical examples with code

1. What Are Angular Modules?

Angular modules, defined using the @NgModule decorator, are containers for components, directives, pipes, and services. They group related functionalities and allow Angular to compile and bootstrap the application efficiently.

Why Use Modules?

  • Organize code logically
  • Enable reusability of components, directives, and pipes
  • Improve maintainability
  • Allow lazy loading for performance optimization
  • Simplify testing

Module Structure

A basic module includes:

  • Declarations: Components, directives, and pipes belonging to the module
  • Imports: Other modules whose exported classes are needed
  • Providers: Services available within the module
  • Bootstrap: Root component for bootstrapping the module (only for root module)
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

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

2. Types of Angular Modules

Angular modules can be categorized into three main types:

  1. Root Module
  2. Feature Modules
  3. Shared Modules

2.1 Root Module (AppModule)

The Root Module is the starting point of an Angular application. It bootstraps the application and typically contains global imports and providers.

Example

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { AppRoutingModule } from './app-routing.module';

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

Explanation:

  • declarations include components used in this module.
  • imports include other modules needed globally.
  • bootstrap identifies the root component (AppComponent) to launch the app.

2.2 Feature Modules

Feature Modules organize functionality into specific application domains, making code modular and maintainable. Each feature module may have its own components, services, and routes.

Creating a Feature Module

ng generate module products

Example: ProductsModule

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProductListComponent } from './product-list/product-list.component';
import { ProductDetailComponent } from './product-detail/product-detail.component';
import { RouterModule } from '@angular/router';

@NgModule({
  declarations: [ProductListComponent, ProductDetailComponent],
  imports: [
CommonModule,
RouterModule.forChild([
  { path: 'products', component: ProductListComponent },
  { path: 'products/:id', component: ProductDetailComponent }
])
] }) export class ProductsModule {}

Benefits of Feature Modules:

  • Modularize application features
  • Reduce root module complexity
  • Support lazy loading
  • Improve maintainability and testability

2.3 Shared Modules

Shared Modules contain reusable components, directives, and pipes used across multiple modules.

Example: SharedModule

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HighlightDirective } from './highlight.directive';
import { CustomPipe } from './custom.pipe';

@NgModule({
  declarations: [HighlightDirective, CustomPipe],
  imports: [CommonModule],
  exports: [HighlightDirective, CustomPipe, CommonModule]
})
export class SharedModule {}

Explanation:

  • declarations include components, directives, and pipes.
  • exports allow other modules to use the declared components/pipes.
  • imports include commonly required modules like CommonModule.

Usage in Feature Module:

import { SharedModule } from '../shared/shared.module';

@NgModule({
  imports: [SharedModule],
})
export class ProductsModule {}

3. Organizing Large Applications Using Modules

For enterprise applications, proper module organization is critical. A typical structure may include:

app/
  app.module.ts
  core/
core.module.ts
services/
shared/
shared.module.ts
components/
directives/
pipes/
features/
products/
  products.module.ts
  components/
users/
  users.module.ts
  components/

Core Module

The Core Module contains singleton services and app-wide providers. It is imported only in the root module.

import { NgModule, Optional, SkipSelf } from '@angular/core';
import { AuthService } from './services/auth.service';

@NgModule({
  providers: [AuthService]
})
export class CoreModule {
  constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
if (parentModule) {
  throw new Error('CoreModule is already loaded. Import only in AppModule.');
}
} }

Explanation:

  • SkipSelf ensures CoreModule is loaded only once.
  • Provides singleton services for the entire app.

4. Lazy Loading Modules

Lazy loading improves application performance by loading feature modules only when needed.

Setting Up Lazy Loading

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: 'products', loadChildren: () => import('./features/products/products.module').then(m => m.ProductsModule) }
];

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

Benefits:

  • Reduces initial load time
  • Efficient resource usage
  • Improves user experience

5. Dependency Injection and Modules

Modules help organize providers for dependency injection:

  • Root Module Providers: Available globally
  • Feature Module Providers: Scoped to the feature module
  • Shared Module Providers: Avoid providing services here to prevent multiple instances

6. Best Practices for Angular Modules

  1. Use Root Module for bootstrapping and global imports.
  2. Use Feature Modules for distinct application areas.
  3. Use Shared Module for reusable components, pipes, and directives.
  4. Use Core Module for singleton services.
  5. Avoid providing services in SharedModule to prevent multiple instances.
  6. Leverage lazy loading for feature modules.
  7. Keep modules cohesive – each module should serve a specific purpose.
  8. Follow naming conventions (feature.module.ts, shared.module.ts, core.module.ts).
  9. Import CommonModule in every feature/shared module.
  10. Keep module declarations and imports organized to improve readability.

7. Practical Examples

Example: E-Commerce Application

app/
  app.module.ts
  core/
core.module.ts
services/auth.service.ts
shared/
shared.module.ts
components/header.component.ts
pipes/currency.pipe.ts
features/
products/
  products.module.ts
  product-list.component.ts
  product-detail.component.ts
users/
  users.module.ts
  user-profile.component.ts

AppModule:

@NgModule({
  imports: [BrowserModule, AppRoutingModule, CoreModule, SharedModule],
  bootstrap: [AppComponent]
})
export class AppModule {}

Lazy Loaded Products Module:

const routes: Routes = [
  { path: '', component: ProductListComponent },
  { path: ':id', component: ProductDetailComponent }
];

@NgModule({
  imports: [CommonModule, RouterModule.forChild(routes), SharedModule],
  declarations: [ProductListComponent, ProductDetailComponent]
})
export class ProductsModule {}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *