Discovering Feature Modules

Mic B. || Angular Lead Programmer
6 min readJan 11, 2022

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

When you start a new Angular project, your application always includes a root module (AppModule) and, if you ask for it, a routing module. While it is possible to have only one module for your whole application, it is not a good solution. The best practice is to break it down into smaller feature modules. I will argue that feature modules are the keystone to a scalable application.

In this article, we will define the different types of feature modules, discuss why it is best practice to use them, and learn how to implement them.

Defining feature Modules

The only difference between a feature and root modules is their function. The root module should be used to load a specific set of building blocks at the start of the application and to organize the rest of the modules. Feature modules should provide a defined set of functionalities oriented toward a single feature.

Angular feature modules can be organized into 5 categories:

1. Domain feature modules deliver a user experience dedicated to a particular application domain like editing a customer or placing an order. They typically have a top component that acts as the feature root and private, supporting sub-components descend from it. Domain feature modules consist mostly of declarations. Only the top component is exported. Domain feature modules are typically imported exactly once by a larger feature module.

2. Routed feature modules are domain feature modules whose top components are the targets of router navigation routes. All lazy-loaded modules are routed feature modules. They don’t export anything because their components never appear in the template of an external component.

3. A routing module provides routing configuration for another module and separates routing concerns from its companion module. They should define routes, add router configuration to the module’s imports and add guards and resolver services providers to the module’s providers.

4. Service modules provide utility services such as data access and messaging. Ideally, they consist entirely of providers and have no declarations. They should only be imported into the root module.

5. A widget module makes components, directives, and pipes available to external modules. Many third-party UI component libraries are widget modules. They consist entirely of declarations, most of them exported. Import widget modules in any module whose component templates need the widgets.

Why use feature modules?

There are no good reasons for not structuring your application into small well-defined modules. If you are a beginner on the subject, you might see this as a complex topic, and I will agree it is a bit scary. But I can promise you it is worth learning before starting any project on which you plan to create over 50 components.

On the other side, there are plenty of reasons to use them:

1. Better structure and separation of concerns (SOC): It helps define clear boundaries for your features. Creating multiple feature modules forces the programmer to decouple nonrelated functionality and to segment, organize and structure the code. The files are also leaner, cleaner, and easier to maintain.

2. Lazy loading: Feature modules also gives you the ability to implement lazy loading. When the application is started on a web server, the browser downloads all necessary files for it to run successfully. Unless lazy loading is programmed, all the code is loaded, which increases the initial application rendering time. But if some of the modules are lazily loaded, then the code for them is not downloaded on the app’s first run. It will be downloaded only when a user tries to access a functionality that is a part of a lazily loaded feature module.

3. Saves coding time: Since all the artifacts of a particular module are grouped inside the folder of that module, it becomes fast and easy to locate the code.

4. Reusable code: well-segment features into modules makes it very easy to implement into a new application. This will allow you to create your library of reusable components.

Now that we know better what are feature modules, let's look at how to create and use them.

Getting Started

Create an Angular Project

We first need a new angular project. You probably have done that a million times, but just in case:

1. Open visual studio and click File -> Open Folder. Select the folder in which you would like to create your application.

2. Open a new terminal by pressing ‘Ctrl + ~’ and type ng new feature-modules.

3. Add the routing.

  1. Choose your favorite style sheet format.

You should now have a perfectly working angular app.

The next step will be to clean the app.component.html and replace everything contained in that file by:

<h1>Hello World</h1>

In the terminal of your Code editor, run ng serve. Here is what you should see:

Creating a Feature Module

To avoid serving our application every time we want to use the terminal; I recommend opening a second terminal for the next commands.

Creating a module can be done by running the command ng g m feature (or ng generate module feature if you prefer). This will create a feature folder in your app folder with the feature module inside it.

Creating a component inside your feature module

Now, we have a feature module, and we want to create a component inside it to demonstrate how we can use it in our application.

We will need to access the feature module using the terminal with the command cd src/app/feature

Once it is done, we will create the feature component using the terminal with the command ng g c feature. This will creature a new feature folder inside which you will find your component files and will automatically import the component inside the declaration array feature module.

Since components inside a module are limited by its scope, you will need to declare it inside the export array if you want to use it anywhere else in the application.

Even though we did declare the feature component as public, we need to connect the feature module to the root module. For that add it to the imports array of the AppModule.

You can now safely use the feature component anywhere. This strategy of module declaration is called eager loading and gives access to the building blocks inside the feature module right at the initial rendering of the application.

Conclusion

In this article, we have learned that the only difference between the root and feature module is their function and in the content they organize. We have discovered that feature modules can be defined in five major type: domain module, routed feature module, routing module, service module and widget module. Finally, we have discussed that featured modules allow for better structure and separation of concept (SOC), lazy loading, save coding time and help to reuse code.

Afterward, we built a feature module using an eager loading strategy and we discovered how to connect its component to use it in the rest of the application.

Stay tuned for the last article of this series where we will discuss lazy loading in-depth and will learn how to create a feature module using this strategy. We will also discover how to preload such a module.

--

--

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.