Mastering Angular Components
上QQ阅读APP看书,第一时间看更新

Angular NgModule

Organizing an application solely by composing components comes with some challenges. Angular supports the concept of application modules, which essentially are just containers around components that help structure your application.

The concept of NgModule was introduced to mainly solve the following issues:

  • Explicit template parsing:
    With the use of modules and by declaring all components, directives, pipes, and providers which are used inside of your application module, Angular is able to parse HTML templates very explicitly. This is really helpful when it comes to debugging. Let's say you're including an element within one of your component templates which does not match any of the selectors specified by the components within your module. Angular can now assert an error because you explicitly told it what components are available within your module. Without telling Angular which components belong to your application module, it would not be able to know if you're including a non-existing component within your template.
  • Simpler dependency resolution:
    Since Angular can now simply resolve your main application module to find out what components are present within your application, things get simplified a lot. Imagine you have a very complex application existing of hundreds of components. Without modules, Angular would need to follow each individual component to find out how they are dependent on each other. With modules, Angular can simply check what components are declared inside of the module to find all components.
  • Lazy loading with the Angular router:
    The router of Angular is able to load parts of your application lazily when required. This is a very powerful feature, but it requires that you declare a bundle of application artefacts like components or directives, to be loaded asynchronously after your main application has started. NgModule comes in very handy at this point. By creating a separate module using NgModule, you can now define a part of your application consisting of new components and other artefacts. Within the build of your application, this module is then built separately into its own JavaScript resource, which can be loaded asynchronously at runtime by the router.

Your application requires at least one main module, which is declaring all your application components. Let's look at a very simple example and build the main module for our HelloWorld component:

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {HelloWorldComponent} from './hello-world.component';
import {ShoutOutComponent} from './shout-out.component';

@NgModule({
declarations: [HelloWorldComponent, ShoutOutComponent],
imports: [BrowserModule],
bootstrap: [HelloWorldComponent]
})
export class HelloWorldAppModule { }

Similar to a component definition, we're using an ES6 class and a decorator to define an Angular module. The NgModule decorator of our main application module has three configuration properties:

A module dependency tree: Module A importing module B and C so that all components are available to module A

The declarations property is used to tell Angular what components, directives, and pipes are present within this module. If our application consists of 30 components, we need to add them all to the declarations of the NgModule. Every time you create a new component, you will also need to add it to the declarations array within your application module.

Within the array of the imports property, we can tell Angular to import other NgModule. This way, you can compose your application modules from many smaller modules if you like. However, there's no real benefit of structuring your application into submodules, unless you're exporting a submodule as a library, or if you're using the lazy loading feature of the router, as discussed earlier. It's crucial that you always import the Angular BrowserModule within your main application module. The BrowserModule contains all the Angular core components, directives, and other dependencies which are required in order to run your application within a browser environment.

Finally, the bootstrap property is telling Angular which of your components should be rendered first. You should specify your main application component here, which is representing the root component of your application. In the second chapter of this book, we'll take a closer look at the bootstrapping mechanism of Angular.