Search code examples
angularlazy-loadingangular4-router

Lazily loaded module in Angular 4 errors with "Component X is not part of any NgModule"


I have an app with loads of modules. It works perfectly. I want to make one module lazy load as it is not often hit by normal users.

So, I change the route for LazyModule to use loadChildren, the main app still loads ok, but when I try and hit one of the child routes of LazyModule, it gives me this error:

Error: Uncaught (in promise): Error: Component HomeComponent is not part of any NgModule or the module has not been imported into your module.

HomeComponent is not used in LazyModule. It is part of a different module, call it MainModule.

MainModule and LazyModule are both imported and exported to/from ComponentsModule which then gets imported into the app.module.

There is also SharedModule which is imported to all the other modules mentioned.

So my questions:

  • Why does LazyModule try to load components in MainModule when it has absolutely no dependencies on it?
  • Why does it work with normal routing, but not with lazy loading?

Thanks in advance for your help.

Modules are here:

LazyModule

import ...;

const routes: Routes = [
    {
        path: '',
        redirectTo: '/lazy-page/1',
        pathMatch: 'full'
    },
    {
        path: '1',
        component: LazyPage1Component
    }
];

@NgModule({
  imports: [
      RouterModule.forChild(routes),
      SharedModule
  ],
  declarations: [
      LazyPage1Component
  ]
})
export class LazyModule { }

MainModule

import ...;

@NgModule({
  imports: [
      SharedModule
  ],
  declarations: [
      HomeComponent
  ],
  exports: [
      HomeComponent
  ]
})
export class MainModule { }

ComponentsModule

import ...;

@NgModule({
  imports: [
    SharedModule,
    MainModule,
    LazyModule
  ],
  declarations: [],
  exports: [
    SharedModule,
    MainModule,
    LazyModule
  ]
})
export class ComponentsModule { }

AppModule

import ...;

@NgModule({
  imports: [
    ComponentsModule
  ],
  declarations: [
    AppComponent
  ],
  providers: [{provide: APP_BASE_HREF, useValue : '/' }],
  bootstrap: [AppComponent]
})
export class AppModule { }

AppRoutingModule

const routes: Routes = [
{
    path: '',
    component: HomeComponent
},
{
    path: 'lazy-page',
    loadChildren: './components/lazy/lazy.module#LazyModule',
},

EDIT: I found a hack to get around it for now, but I really want a proper solution. The hack is just to import every single module in my app into LazyModule as well as AppModule. This is a terrible solution, because the whole idea of having a lazy-loaded module is to decouple it from the rest of the app as it is separate. I don't want to import everything twice, and nor should I need to since none of the modules imported are ever used or referenced inside LazyModule.


Solution

  • Thanks to @Dmitry Grinko I re-organised my router, which led me to find that I had randomly imported app-routing.module into a different module.

    The solution was to remove this extra import, and it all worked.