Working with Multiple Angular Modules and Module Routing

This is a practical guide on how you can use multiple modules in your Angular project and configure an optimum module routing.

Why use multiple modules in Angular?

Using multiple modules is highly recommended as it gives you multiple advantages over a single module architecture. If you are creating a sophisticated system which may be extensively used it can help optimize the application while also helping you in a better source code management. Before quickly moving towards the solution lets look at few benefits of using multiple modules:

  • Helps you organize your source code in ‘packages’
  • Its possible to lazy-load modules, so that only modules which are being used right now are loaded and others loaded on-demand. This can be achieved by module routing as you will see below.
  • You can reuse the same module in multiple applications for eg, a login module can be reused between various enterprise applications using same auth provider and mechanism.

Steps

Let’s delve into the steps.

  1. Create new module
  2. Reuse components
  3. Routing between modules

1. Creating New Module

Creating new module is pretty easy and a single CLI job.

ng generate module module_name

If you want to use routing, you can enable by default by using the following:

ng generate module module_name --routing=true

All set of options can be figured out here in Angular ng CLI documentation.

Creating components in the module

When a new module is created using ng CLI, a new folder is created with the module name and a module_name.module.ts file is generated inside that. All new components that you want to add to the module should ideally be inside the same folder. For creating a new component you can use the following CLI command.

ng generate component component_name --module module_name

Doing this will automatically import the component definition in the module.ts file and you are good to go. By now your module.ts file should look something like the following given that the module name is HomeModule and sample component name is MainMenuComponent:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MainMenuComponent } from './main-menu/main-menu.component';

@NgModule({
  declarations: [MainMenuComponent],
  imports: [
    CommonModule
  ]
})
export class HomeModule { }

The MainMenuComponent is highlighted on Line 3 and Line 6

2. Reuse Components

One of the primary goal of using the modules is re-usability within and outside the current project. To do that, the components which needs to be reused needs to be exported from the module’s module.ts file and imported (yes, just like you import third party modules) to the place where you wish to import.

This is how you export a component:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MainMenuComponent } from './main-menu/main-menu.component';
import { RouterModule } from "@angular/router";

@NgModule({
  declarations: [MainMenuComponent],
  imports: [
    CommonModule
  ],
  exports: [
    MainMenuComponent
  ]
})
export class HomeModule { }

And similarly, the place where you would like to use it, you will need to import the module as shown below:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { HomeModule } from "./modules/home/home.module"
import { CoreModule } from "./core/core.module";

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    HomeModule,
    CoreModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Its a blessing to be able to re-use your components so easily. I personally have created my own visualization libraries which I love to use in my private projects. You will find them soon up for grab and source code released on GitHub. Now comes the last part, its routing!

3. Routing between modules and enabling lazy-loading

If you have created an Angular project with routing enabled your project would look something like this:

[-] project name
    [+] e2e
    [+] node_modules
    [-] src
        [-] app
            -  app.component.ts
            -  app.component.html
            -  app.component.scss
            -  app.component.spec.ts
            -  app-routing.module.ts
            -  app.module.ts
        [+] assets
        [+] environments
         -  favicon.ico
         -  index.html
         -  styles.scss
....
....     

The major thing here is the separate routing file and the primary module definition in app.module.ts. If you didn’t enable routing, don’t worry you can create it yourself or even code it inside app.module.ts. After all, this file just creates and abstraction to help you make your code tidier. Dividing your code into multiple modules can help you to ensure only the required part of your application is loaded. The other parts of the application can be loaded when they are required. For eg, if we our application has a separate bookings module which should only load when we are dealing with bookings, we can ensure that by lazy-loading the bookings module. Here is how it works:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    redirectTo: '/home',
    pathMatch: 'full'
  },
  {
    path: 'home',
    loadChildren: () => import('./modules/home/home.module').then(m => m.HomeModule)
  },
  {
    path: 'bookings',
    loadChildren: () => import('./modules/bookings/bookings.module').then(m => m.BookingsModule)
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Lines 11 & 12 ensures the HomeModule loads when you navigate to /home sub-url. Similarly, BookingsModule will only load when you navigate to /bookings sub-url as seen in lines 15 & 16.
Lines 6, 7 & 8 ensures that by default the user is redirected to /home sub-url and that implies HomeModule will start lazy-loading after redirection.

To make it work seamlessly, the next thing you need to do is go to the container component, in this case, app.component.html and add a <router-outlet> tag which ensures the routed component is loaded inside the tag.

<user-header></user-header>
<div class="main-container">
    <router-outlet></router-outlet>
</div>
<user-footer></user-footer>

Routing within internal modules

Okay, so you should have perfectly have a multi-module architecture up and running by now but how do you route inside the module? Just check out this home.module.ts and you will realize it is similar to how we create routes in a single-module setup. The ONLY difference is this time, you would want to call RouterModule.forChild(). You can find the description here why we use it this way. For starters, it just helps you to configure sub-routes without disturbing rest of the application. So now, your home.module.ts should look like this:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MainMenuComponent } from './main-menu/main-menu.component';
import { RouterModule } from "@angular/router"

@NgModule({
  declarations: [MainMenuComponent],
  imports: [
    CommonModule,
    RouterModule.forChild([
      {
        path: '',
        component: MainMenuComponent
      }
    ])
  ]
})
export class HomeModule { }

That should be it! Here are some more resources that you should checkout if you would love to learn more:

Hope this act as a reference to you. In case of doubt, confusion or feedback drop down a comment below or you can also use the contact us section! Happy Coding!

GC

You May Also Like

About the Author: Gaurav Chouhan

Gaurav is an independent senior software consultant and trainer based out of India with more than 5 years of experience in cloud computing specifically on Microsoft Azure, full-stack development on .net core and angular and mobile programming on Android and UWP. For business opportunity, please use the contact section.

Leave a Reply

%d bloggers like this: