Understanding NgModule

This article is the first of a series about an in-depth understanding of Angular Modules and it details introduction concepts. The next two articles are discussing feature modules and optimizing your application with lazy loading.

Every Angular application needs to have a least one module, but It can also be divided into numerous ones. You surely have seen one already, as it is included in the boilerplate of every new Angular application created with the ng new application-name Command Line (CL) command. But what are they really? How do they work? What are the best practices? We will answer those questions by discussing the following topics:

· The nature of modules

· Their purpose

· Their architecture

· Their scope and interaction

· How to implement them in our global application architecture.

What are Angular Modules?

While discussing modules in this series, we will be referring to the Angular Modularity System called NgModule, unless specified.

A module is simply a class with the @ngModule() decorator. It groups Angular primitives (components, directives, services, pipes, guards, other modules, etc.) that are related, in a way that can be combined with other modules to create an application. An Angular application can be thought of as a puzzle where each module is needed to be able to see the full picture.

NgModules are different than JavaScript ECMA 2015 modules. The latest is the ones you refer to when you import a code file, into another code file with the following syntax:

import { NgModule } from ‘@angular/core’;

What is the module’s purpose?

Angular modules are useful for organizing and splitting up an application into smaller parts (that can be loaded separately) and to create libraries of components that can be easily imported into other applications.

Because Angular doesn’t scan all building blocks in your project, we must let it know which of them is to be loaded and that they are needed. To do so, features must be declared in a module. How and where you include them depends on the type of feature you are importing.

Where to import the different features?

Let’s look at the template of an application module to understand better how and where to import the different features:

Components, pipes, and custom directives will be imported under the declarations array, the other modules, like the routing modules, angular feature modules or third-party library modules will be added to the imports array while services, guards, and other data providers will be added in the providers’ array.

The bootstrap array is used to declare which component is used at the start of the application.

The (not-so) special routing Module

The routing module is exactly like any other module. It is simply there to hold our routing configuration. It could be added to the root module of your application. We usually outsource it because there is a lot of code and it keeps the application module leaner, more focused, and easier to maintain.

The routing module imports the RouterModule that angular offers and calls a method that allows us to pass in the routes we wish to define.

For the routing module to be considered into the scope of the application, we will have it declared in the exports array of the routing module and declare it in the imports array of the application module.

Modules are private

This is also true for other modules. Modules are private. Every feature you declare into them will have its scope limited to the scope of the module. It means that to be able to use a feature outside the scope of this module, you must declare it in the exports array of a module and import this module into the other module where you want to access this feature. Just like we did with the RouterModule. Not so complicated, right?

Single app module or many modules?

When you import another module, you import everything that is declared in the module exports array. This concept is important for a larger application. Breaking down your modules into tiny ones will allow you to limit the code that is loaded and enhance performance and maintainability.

If you have a small application, it is perfectly acceptable to have a single module. The more your application grows, the more plenty of modules will be a better option. Consider this when you are designing the component architecture of your next application. It might save you a headache further in development.

Summary

In short, Angular Modules are private logical groups of Angular components, directives, pipes, and services that allow us to split up the application functionality into logical parts, with their internal details like services or components. They allow Angular to have access to different building blocks of your application. The way you import features in a module depends on their nature.

Finally, I will argue that creating an application with a larger amount of modules is usually a better option. Why? Reusability. On top of getting better performance and cleaner code, the main advantage of creating modular code is that your code becomes easily reusable. Remember, a module is a segmented block of code. It means that if you pick it up from one application, you can easily drop it in the next one and it will be able to work with limited action on your behalf.

This will speed up your workflow and give you more time to work on new challenges allowing you to become a better dev, and not repeat endlessly the same patterns.

I hope this has helped you understand modules a little better and thanks for reading.

--

--

Mic B. || Angular Lead Programmer

Web programmer for two years now. I learned on my own and started out by freelancing before finding my first programming position at APRIL Canada.