简体   繁体   中英

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.

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.

Try to use this AppRoutingModule

const routes: Routes = [
{
    path: '',
    redirectTo: '',
    pathMatch: 'full',
},
{
    path: '',
    component: AppComponent,
    children: [
        {
            path: '',
            loadChildren: './path/to/main.module#MainModule',
        }
    ]
},
{
    path: 'lazy-page',
    component: AppComponent,
    children: [
        {
            path: '',
            loadChildren: './components/lazy/lazy.module#LazyModule',
        }
    ]
}

Your app.component

<router-outlet></router-outlet>

MainRoutingModule

{
    path: '',
    component: HomeComponent
},

And this is your LazyModule routes

const routes: Routes = [
    {
        path: '1',
        component: LazyPage1Component
    }
];

And remove ComponentModule

Hope it helps

Looking at your code, I just want to comment that lazy loaded modules need not be imported into your app module as your are adding it to Component module and importing to app module.

Lazy loaded modules can remain as independent module from app and will be loaded when the route needs activation.

I had the same issue and similar to what @Dmitry suggested I simply removed all routes from my AppRoutingModule and left the root + the lazy loaded module route. I got a different error message like @DoubleA mentions in the comments.

RouterModule.forRoot() 调用了两次

In the end I was importing AppRoutingModule in my SharedModule which at the same time was also being imported in the lazy loaded module. I'll have to refactor to avoid AppRoutingModule.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM