Understanding Angular Modules

A quick but comprehensive guide for understanding the different types of Angular Modules

Understanding the different types of Angular modules is a key factor for architecting or refactoring an application.

The concept of Angular modules has matured since they were first introduced in the framework in a late RC release.

But as years have passed, both the Angular team and the community have come up with guidelines that explain what the different types of modules are, and what they are for.

Anatomy of an Angular Module

Angular modules are made of a simple set of properties and one lifecycle hook. In order to fully understand modules, we want to first inspect each property and what they are for.

Let’s have an overview of the NgModule interface:

Declarations

Maybe the simplest and most used property, we use the declarations array for importing components, directives, and pipes.

Providers

Another commonly known property, we use the array providers for defining services that have been decorated with the Injectable decorator, which makes them accessible via the Angular DI.

Imports

We use the imports array for importing other modules.

Exports

By default, everything defined in a module is private. Exports is an array that allows the declarations and the declarations within a module accessible from the modules that import the module where these are defined.

EntryComponents

EntryComponents specifies the list of components compiled when the module is bootstrapped. These components are not components defined in a template but are normally loaded imperatively, for example using ViewContainerRef.createComponent().

An example is routing components, but the framework adds them to entryComponents automatically.

Bootstrap

Bootstrap also specifies components compiled when the module is bootstrapped and automatically adds them to entryComponents.

Id

A name that identifies the module

Schemas

The allowed values for this property are NO_ERRORS_SCHEMA or CUSTOM_ELEMENTS_SCHEMA that you may want to use when using, for instance, a web component.

I recommend using this with care, as components that you may have left undefined will not throw an error.

It’s something that can be normally used when testing when you do not want to test components you haven’t defined in the module. But always use being aware of what is actually being skipped by the compiler.

JIT

This property will make the framework always compile the module using JIT rather than AOT.