Essential Angular: NgModules

Victor Savkin is a co-founder of nrwl.io, providing Angular consulting to enterprise teams. He was previously on the Angular core team at Google, and built the dependency injection, change detection, forms, and router modules.
This is the second post in the Essential Angular series, which aims to be a short, but at the same time, fairly complete overview of the key aspects of Angular. In this post I’ll cover NgModules.
Example App
Throughout this series I will use the same application in the examples. This application is a list of tech talks that you can filter, watch, and rate.

You can find the source code of the application here.
Declarations, Imports, and Exports
NgModules are the unit of compilation and distribution of Angular components and pipes. In many ways they are similar to ES6 modules, in that they have declarations, imports, and exports.
Let’s look at this example:
Here we define two modules: TalksModule and AppModule. TalksModule has all the components and pipes that do actual work in the application, whereas AppModule has only AppCmp, which is a thin application shell.
TalksModule declares four components and one pipe. The four components can use each other in their templates, similar to how classes defined in an ES module can refer to each other in their methods. Also, all the components can use FormattedRatingPipe. So an NgModule is the compilation context of its components, i.e., it tells Angular how these components should be compiled. As with ES, a component can only be declared in one module.
In this example TalksModule exports only TalksCmp — the rest is private. This means that only TalksCmp is added to the compilation context of AppModule. Again this is similar to how the export keyword works in JavaScript.
Summary
- NgModules are akin to ES modules: they have declarations, imports, and exports.
- NgModules define the compilation context of their components.
Bootstrap and Entry Components
The bootstrap property defines the components that are instantiated when a module is bootstrapped. First, Angular creates a component factory for each of the bootstrap components. And then, at runtime, it’ll use the factories to instantiate the components.
To generate less code, and, as a result, to produce smaller bundles, Angular won’t generate component factories for any TalksModule’s components. The framework can see their usage statically, it can inline their instantiation, so no factories are required. This is true for any component used statically (or declaratively) in the template.
For instance, let’s look at TalkCmp:
Angular knows, at compile time, that TalkCmp uses WatchButtonCmp and RateButtonCmp, so it can instantiate them directly, without any indirection or extra abstractions.
Now let’s look at a different component that uses the router.
Angular cannot statically figure out what components can be loaded into the outlet, and, as a result, cannot instantiate them directly. Here we need the extra abstraction, we need the component factories for both TalksCmp and SettingsCmp. We can tell Angular to generate those by listing them as entry components.
Even though we do not use TalksCmp or SettingsCmp in any template, the router configuration is still static. And it is cumbersome to declare every component used by the router in the entry components. Because this is so common, Angular supports a special provider token to automatically pre-populate entryComponents.
And when using RouterModule.forRoot or RouterModule.forChild, the router module takes care of it.
Summary
- To be more efficient, Angular separates components used statically (declaratively) from the components used dynamically (imperatively).
- Angular directly instantiates components used statically; no extra abstraction is required.
- Angular generates a component factory for every component listed in entryComponents, so that they can be instantiated imperatively.
Providers
I’ll cover providers and dependency injection in an upcoming blog post. Here I’d like to just note that NgModules can contain providers. And the providers of the imported modules are merged with the target module’s providers, left to right, i.e., if multiple imported modules define the same provider, the last module wins.
Injecting NgModules and Module Initialization
Angular instantiates NgModules and registers them with dependency injection. This means that you can inject modules into other modules or components, like this:
This can be useful for coordinating the initialization of multiple modules, as shown below:
Bootstrap
To bootstrap an Angular application in the JIT mode, you pass a module to bootstrapModule.
This will compile AppModule into a module factory and then use the factory to instantiate the module. If you use AOT, you may need to provide the factory yourself.
I said “may need to” because the CLI and the WebPack plugin take care of it for you. They will replace the bootstrapModule call with bootstrapModuleFactory when needed.
Lazy Loading
As I mentioned above NgModules are not just the units of compilation, they are also the units of distribution. That is why we bootstrap an NgModule, and not a component — we don’t distribute components, we distribute modules. And that’s why we lazy load NgModules as well.
The loader compiles the modules if the application is running in the JIT mode, and does not in the AOT mode. The default loader ‘@angular/core’ ships with uses SystemJS, but, as most things in Angular, you can provide your own.
Summary
- NgModules are the units of compilation. They tell Angular how components should be compiled.
- Similar to ES module they have declarations, imports, and exports.
- Every component belongs to a NgModule.
- Bootstrap and entry components are configured in NgModules.
- NgModules configure dependency injection.
- NgModules are used to bootstrap applications.
- NgModules are used to lazy load code.
Essential Angular Book
This article is based on the Essential Angular book, which you can find here https://leanpub.com/essential_angular. If you enjoy the article, check out the book!
Victor Savkin is a co-founder of Nrwl — Enterprise Angular Consulting.

If you liked this, click the💚 below so other people will see this here on Medium. Follow @victorsavkin to read more about Angular.