Understanding the Angular Root App Module
This guide covers the Angular module system and how to use it to structure an app and ensure it follows the separation of concerns design principle.
Sep 29, 2020 • 5 Minute Read
Introduction
The more complex your app is, the more important it is to adhere to the separation of concerns design principle. In software engineering, separation of concerns is a design principle where you split your program or app up into different areas of intent. For instance, in an Angular app for showing movie ratings, you may have the following pieces of functionality:
- Display movie information
- Provide user profiles
- Fetch movie information
- Allow rating of movies
- Recommend new movies
At first glance, this seems straightforward. However, even an app that only needs the above features can quickly become unwieldy without properly separating each piece of functionality into its own self-contained area within the code. Modules are how you ensure that your Angular app follows this design principle. In this guide, you will learn about the Angular module system. You will learn how you can use this system to properly structure your app with special focus on the root app module.
Let's dive in!
Root Application Module
Angular modules are the top-level architectural type within your Angular app. Modules exist at the highest level of abstraction available within the Angular framework. Everything in your app is ultimately structured around modules. This is powerful! It means that you can easily encapsulate code within a module and share or reuse it throughout your app. When looking at the Angular module system, all things must begin with the root app module.
The root app module is a necessary portion of every Angular app. By default, this module is named AppModule, although it is possible to rename this module if you so choose. The AppModule is the entry point to your app. You can think of the AppModule in a similar fashion to the main function that is available in other languages such as C# and C++. Acting as an entry point, it is also the top-level container for your app's functionality and view layer.
When you generate a new Angular app, the AppModule is generated at src/app/app.module.ts and looks like this:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Ideally, you want to keep your AppModule as slim and as unchanged from the above code as possible. You can keep your AppModule slim via the following techniques:
- Only import modules that are absolutely necessary for your app to load initially
- Only declare Angular components, directives, or pipes that you want globally available
By following these two principles, you can ensure that your app doesn't become bloated. The question is, "How is it possible to follow these two principles?" I mean, after all, you need more components and functionality in your app! The answer lies within feature modules and lazy loading. The term feature modules was coined to describe the best practice of creating different modules within your Angular app that correspond to different features of your app. Lazy loading is a term used to describe the ability of your app to load JavaScript "lazily" on an on-demand basis.
Following the example of the movie app above, you could have a feature module that is entirely responsible for recommending new movies. This module might look like this:
...
@NgModule({
declarations: [
RecommendationComponent,
RecommendationChartComponent,
ApprovalComponent
],
imports: [
BrowserModule,
ReactiveFormsModule,
SharedModule
],
providers: []
})
export class RecommendationModule { }
But be careful! You don't want to import this new feature module into the AppModule unless you explicitly mean to. By ensuring that this feature module is connected to a lazily loaded route, you can ensure that your AppModule doesn't load your feature module eagerly and that the RecommendationModule is instead loaded on demand. This means that your bundle size is smaller and that your app continues to load speedily!
Lazy loading is a big topic in and of itself, and thus it is beyond the scope of this guide. For more info on lazy loading, check out this related Pluralsight guide.
Conclusion
The root app module is just the beginning. It is a necessary part of any Angular app, but it is also just the entry point to the rest of your app's feature modules. A healthy Angular app imports only exactly what is needed within the root AppModule because all of the JavaScript within this module is eagerly loaded. By importing the bare minimum into your AppModule, you can ensure that your app loads as fast as possible.
To learn more about Angular modules and how you can use them to structure your app in the way that makes the most sense, check out the Angular module documentation.