Grasping the Concept of Angular Modules
When we talk about Angular, one of the core ideas we have to get comfortable with is the notion of an Angular Module. At its heart, a module is just a container—a way to group related pieces of code together under a single logical umbrella.
In an Angular-specific sense, this container groups together things like components, custom directives, custom pipes, and services (a topic I will dive deeper into later).
When you scaffold a new project with the Angular CLI, you are handed a ready-made module: app.module.ts. To get a clear picture of what makes up an Angular module, let's take a look at the code you'd typically see in that file and break it down piece by piece.
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 { }
Here are the critical essentials to remember from that snippet:
- A module is, fundamentally, a TypeScript class.
- This class gets its special status from the
@NgModuledecorator. - That decorator is a function that takes an object—often called the metadata object. Keep that term handy.
- The metadata object tells Angular everything it needs to know to compile and get the app running.
While the default module only uses a handful of the available metadata options, there are actually nine in total. Let's go through each one and its purpose. Note that some of these are advanced and we'll look at them in detail further down the road.
declarations
- This is an array of classes.
- It lists all the user-created components, directives, and pipes that belong to this module.
- Everything you put in this list becomes a part of the module's scope.
Important Caveat: A component, directive, or pipe class can only be listed in the declarations of a single module. Declaring it in multiple modules will cause a compile-time error.
imports
- This array holds the modules that the current module depends on to work correctly.
- In the example above,
BrowserModuleis listed, indicating a dependency on it.
providers
- This is the array for listing dependency injection providers.
- In simpler terms, this is generally where the module-level services go. We'll come back to this when we cover services in depth.
exports
- This array lists the components, directives, and pipes that the module makes publicly available for other modules to use.
- Follow the logic: this module exports some things; another module wants them; that module must put this module's name in its own
importsarray.
entryComponents
- This is the list of components that Angular pre-compiles when the module is created.
- Every app has at least one entry component: the root
AppComponentby default. - Any component that is created dynamically needs to be added to this list.
bootstrap
- Contains the components that Angular initializes when the app starts.
- Any component listed here is automatically added to the
entryComponentslist.
schemas
- This is the list of elements and properties that are neither standard components nor directives. This is a more advanced topic for later.
id
- A unique identifier that lets the module be looked up via
getModuleFactory. If this isn't set, the module remains unregistered with that factory.
jit
- If this flag is present, the module is completely ignored by the AOT compiler. This is another advanced aspect to be covered later.
The main value of a module is organizational. It gives you a tool to cluster related items into cohesive groups.
Say you have a dashboard feature. All the components related to that dashboard would sit inside its own dedicated module.
That's the core idea behind modules. In the next piece, I will look at how to create your own custom module in Angular.
Cheers!!!
Happy Coding
