Angular - Core and Shared Modules

ยท 564 words ยท 3 minute read

This is a basic and useful pattern you should follow in every Angular application.

The setup of a new Angular application is probably one of the most critical steps. This is when you create the architecture that you will use the rest of the development process. The decisions you take now will impact the entire project.

Apart from organizing the features inside modules and use lazy loading, there is another important pattern you should implement to ease the use and reuse of common elements: the creation of the Core and Shared modules.

In every application, there are a number of services and components that are reused across multiple modules. Instead of declaring these elements in the root AppModule, we will create specific modules for them.

Shared Module ๐Ÿ”—

We create it to define common components and other modules that we need to import inside every other module of our application, so you do not need to import them again and again (like the CommonModule). We only need to add the Shared module to each module to access to common components.

Firt, create a SharedModule:

import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { LoadingComponent } from './components/loading/loading.component';
import { CustomClickDirective } from './directives/custom-click.directive';

@NgModule({
  imports: [CommonModule, RouterModule, HttpClientModule],
  exports: [
    CommonModule,
    RouterModule,
    HttpClientModule,

    LoadingComponent,

    CustomClickDirective
  ],
  declarations: [LoadingComponent, CustomClickDirective]
})
export class SharedModule {}

Once you have created the Shared Module, import it, like the root module:

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

import { AppRoutingModule } from './app-routing.module';
import { SharedModule } from './modules/shared/shared.module';

import { AppComponent } from './app.component';

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

Now, you will be able to use the components declared inside the Shared Module, in the root module. Do the same for the rest of the modules of the application.

Core Module ๐Ÿ”—

The Core Module is a module we create to define common services. The services defined in the Core Module are instantiated once.

This type of module is imported only from the main module, as it contains singleton services that any element in the application can use. We do not want to import it in each module, as this will create additional instances.

Let’s create the Core Module:

import { NgModule, Optional, SkipSelf } from '@angular/core';

import { UserService } from './services/user.service';

@NgModule({
  providers: [UserService]
})
export class CoreModule {
  constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
    if (parentModule) {
      throw new Error(
        'CoreModule is already loaded. Import it in the AppModule only'
      );
    }
  }
}

The Core Module should be imported from the root module only, therefore we are adding a conditional inside the constructor to check it.

In the root module, add the CoreModule to the imports property:

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

import { AppRoutingModule } from './app-routing.module';
import { SharedModule } from './modules/shared/shared.module';
import { CoreModule } from './modules/core/core.module';

import { AppComponent } from './app.component';

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

Congrats! you have created a couple of modules to put inside common components and services, we have improved the structure of the application and it will help the application to scale better.