I am building an Angular 11 application and am trying to create a SharedModule
. I am using lazy loading and wish to avoid loading common modules multiple times across my lazy loaded routes. I created a shared module and imported that into my AppModule
. From my understanding, this shared module should be defined across all lazy-loaded module and not need to be imported anywhere else. However, in my lazy-loaded module, I get an error for not directly importing my shared module. How do I globally define my ProjectSharedModule?
I have my shared module:
@NgModule({
declarations: [ProjectsComponent, TopNavComponent],
imports: [
ChartsModule,
FormsModule,
CommonModule,
RouterModule,
MatDatepickerModule,
MatNativeDateModule,
MatIconModule,
MatInputModule,
MatFormFieldModule,
MatTooltipModule,
],
exports: [
ProjectsComponent,
TopNavComponent,
ChartsModule,
FormsModule,
CommonModule,
MatDatepickerModule,
MatNativeDateModule,
MatIconModule,
MatInputModule,
MatFormFieldModule,
MatTooltipModule,
],
})
export class ProjectSharedModule {}
Here is my AppModule
@NgModule({
declarations: [AppComponent],
imports: [
ProjectSharedModule, // Shared Module should be defined globally
BrowserModule,
AppRoutingModule,
HttpClientModule,
FeaturesModule,
LoggerModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthHttpInterceptor,
multi: true,
},
{ provide: LoggerBase, useClass: LoggerService },
],
bootstrap: [AppComponent],
})
export class AppModule {}
Here is the module that gets lazy-loaded:
@NgModule({
declarations: [
...
MyComponents
...
],
imports: [
RouterModule,
ProfileRoutingModule,
// Shouldn't need these anymore
// CommonModule,
// FormsModule,
// MatDatepickerModule,
// MatNativeDateModule,
// MatIconModule,
// MatInputModule,
// MatFormFieldModule,
// MatTableModule,
// MatTooltipModule,
// Without including this I get an error
// ProjectSharedModule,
],
})
export class ProfileModule {}
Here is the route that lazy loads the module
{
path: 'pr',
loadChildren: () => import('./profile/profile.module').then(m => m.ProfileModule),
canLoad: [AuthorizedUserGuard],
},
Again, how do I share my ProjectSharedModule across all of my lazy loaded routes?
UPDATE
It appears that I need to import my ProjectSharedModule
in my lazy loaded module. According to this article it looks like the AppModule
imports the ProjectSharedModule
which is cached. When the lazy loaded module then tries to import it, it is retrieved from the cache to save from duplication of a module code in runtime. Credit to this answer.
Your SharedModule
needs to be imported in every module use the shared components, no matter if it is lazy-loaded or not.
UPDATE: If you find the ProfileModule using only a few components of SharedModule
, you can include them as a part of ProfileModule.
The other thing you can do is dividing the SharedModule into smaller SharedModules according to their functions and import the one needed only.
So your profile.module.ts should be:
@NgModule({
declarations: [
...
MyComponents
...
],
imports: [
RouterModule,
ProfileRoutingModule,
SharedModule
// Shouldn't need these anymore
// CommonModule,
// FormsModule,
// MatDatepickerModule,
// MatNativeDateModule,
// MatIconModule,
// MatInputModule,
// MatFormFieldModule,
// MatTableModule,
// MatTooltipModule,
// Without including this I get an error
// ProjectSharedModule,
],
})
export class ProfileModule {}