0

thanks for reading. I am trying to lazy load modules with Angular 7 but I am running into an error which I cannot see where I'm doing this incorrectly.

Here's my structure:

/app/routes/app-routing.module.ts

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

import { HomeComponent } from '../pages/home/home.component';
import { RegisterContainerModule } from '../modules/register-container.module';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent
  },
  {
    path: 'register',
    component: RegisterContainerModule
  }
];

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

The homeComponent route routes fine, it's when I try to route to register that I get the issue:

/app/modules/register-container.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { RegisterComponent } from '../pages/register/register.component';

@NgModule({
  declarations: [
    RegisterComponent
  ],
  exports: [
    RegisterComponent
  ],
  imports: [
    CommonModule
  ],
  entryComponents: [
    RegisterComponent
  ],
  bootstrap: [RegisterComponent]
})
export class RegisterContainerModule { }

The registerComponent is default created from ng generate component register and placed in /app/pages/register/ and just says "register works". No other work has been done to it.

My main app-module.ts:

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

import { AppRoutingModule } from './routes/app-routing.module';
import { RegisterContainerModule } from './modules/register-container.module';

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

import { HomeComponent } from './pages/home/home.component';
import { RegisterComponent } from './pages/register/register.component';

...

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

2 Answers 2

1

The lazy loading documentation covers a different approach than you are taking. It has very good coverage of the feature and is recommended reading.

The following shows how to do it in your case:

You can't have code references to the modules you are going to lazy load. If you do then that code ends up in the wrong bundle. So you have to use a string reference.

First off you don't want to register the component in the app-module.ts So remove entryComponents items and the import

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

import { AppRoutingModule } from './routes/app-routing.module';

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

import { HomeComponent } from './pages/home/home.component';

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

Change: /app/routes/app-routing.module.ts to:

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

import { HomeComponent } from '../pages/home/home.component';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent
  },
  {
    path: 'register',
    loadChildren: '../modules/register-container.module#RegisterContainerModule'
  }
];

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

Then you need a routing module routes/register-container-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { RegisterComponent } from '../pages/register/register.component';

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

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

Finally, in your RegisterContainerModule, you will need to import the new RoutingModule. You also don't need the entryComponents section.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { RegisterComponent } from '../pages/register/register.component';
import { RegisterContainerRoutingModule } from '../routes/register-continer-routing.module';

@NgModule({
  declarations: [
    RegisterComponent
  ],
  exports: [
    RegisterComponent
  ],
  imports: [
    CommonModule,
    RegisterContainerRoutingModule
  ]
})

export class RegisterContainerModule { }
Sign up to request clarification or add additional context in comments.

6 Comments

This results in NavigationError(id: 2, url: '/register', error: TypeError: __webpack_require__.e is not a function)
@thatgibbyguy does this occur at runtime or compile time? If at runtime are you visiting the URL directly or via a link on the Home Component?
Runtime, I'm getting that error in my browser's console. I'm getting to the route via routerLink="register" from the homeComponent.
Also, just tried going directly to the route and getting the same issue. This is after a completely new ng serve
I have a working copy of this on my machine now, I edited the answer to include each file.
|
0

In your AppRoutingModule modify the route for register like this

{
path: 'register',
loadChildren: '../modules/registercontainer.module#RegisterContainerModule'
}

The loadChildren will do lazy loading for RegisterContainerModule.

Now once you have lazy loaded RegisterContainerModule, you'll have to create routes (child routes) for this module. Like this

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { RegisterComponent } from './pages/register/register.component';
const childRoutes: Routes = [
{
path: '',
component: RegisterComponent
}
];
@NgModule({
  imports: [RouterModule.forChild(childRoutes)],
  exports: [RouterModule]
})
export class RegisterModuleRoute{ }

See in the routes of Lazy Loaded Module, we are registering routes with forChild method.

More changes you require in your code

1.) You don't need to give a bootstrap component bootstrap: [RegisterComponent] in the RegisterContainerModule

2.) RegisterComponent shall be declared in the RegisterContainerModule only and not in the AppModule.

Thanx

3 Comments

I have been under the impression that this is not lazy loading as code can't be separated into other bundles. RegisterContainerModule needs to be a string reference see my answer.
I tried this method, but I now get Component RegisterComponent is not part of any NgModule or the module has not been imported into your module.
RegisterComponent component must be declared in the module its part of. So make sure its part of the declarations array of the RegisterContainerModule. If its needed in other modules too, then also add it in the exports:[] array of RegisterContainerModule.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.