简体   繁体   中英

angular-cli router lazy loading

I am attempting to run a sample web app to learn how lazy loading with Angular modules works. I generated the app via angular-cli 1.0.0-beta.24 which uses angular 2.4.1. I generated the core app and then 3 components. I then added routing at the app level and directly reference the first two components by importing the components into the app module. For the third component I simply added the routing using the loadChildren method specified in the Angular routing docs . My routing configuration for the main app is as follows:

const appRoutes: Routes  = [
    { path: 'comp1', component: Comp1Component},
    { path: 'comp2', component: Comp2Component},
    { path: 'comp3', loadChildren: 'app/comp3/comp3.module'}
];

export default RouterModule.forRoot(appRoutes);

I turned the code for the third component into a module and removed all imports from the app to the third component. The routing config for the the module is as follows:

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

export default RouterModule.forChild(routes);

When I run the app, the routes for Comp1 and Comp2 work fine, when I click the link for Comp3 (the module route), I get the following error logged to the console:

EXCEPTION: Uncaught (in promise): Error: Cannot find module ./comp3/comp3.module'.
Error: Cannot find module './comp3/comp3.module'.
    at webpackEmptyContext (http://localhost:4200/main.bundle.js:77:8) [angular]

It seems that webpack is not handling the lazy loading. I've tried all kinds of path variants of the "loadChildren" call including:

loadChildren: 'app/comp3/comp3.module#Comp3Module'

with no change in behavior (still get the error above). New to angular2 so may be something in my code, but I see others getting the same error. My google/stackoverflow foo has not lead me to a solution. I added my sample app to my Github account here .

I saw this issue logged by another developer with the Angular team but they kicked it as a support issue to StackOverflow because the sample worked on plunkr. I'm sure there is a clue somewhere in there, but I don't really know enough about webpack and what it is doing to find the differences in the plunkr vs. ng serve run of the app.

Adding additional info. The app's html template looks like this (also available on github repo) :

 <h1>
    {{title}}
 </h1>
 <ul>
    <li><a class="nav-link" routerLink="/comp1" routerLinkActive="active">Component 1</a></li>
    <li><a class="nav-link" routerLink="/comp2" routerLinkActive="active">Component 2</a></li>
    <li><a class="nav-link" routerLink="/comp3" routerLinkActive="active">Component 3</a></li>
  </ul>
  <p></p>
  <router-outlet></router-outlet>

I copied my source tree for this app (from src/app on down) to the angular2 seed project , and with some minor expected tweeks, it runs fine there and continues to fail in the environment set up by angular-cli. The only change I made to my TS source is to use the relative pathing:

{ path: 'comp3', loadChildren: './comp3/comp3.module#Comp3Module'}

for the loadChildren call. I changed my Github example code to reflect this update, but it still fails under the angular-cli environment.

Change your comp3.routes.ts:

export default RouterModule.forChild(routes);

To:

export const comp3Routing = RouterModule.forChild(routes);

On your comp3.module.ts replace:

import comp3Routes from "./comp3.routes";

To:

import { comp3Routing } from "./comp3.routes";

Lastly import comp3Routing, so it should look like this:

@NgModule({
    imports: [
        CommonModule,
        RouterModule,
        comp3Routing,
    ],
    declarations: [
        Comp3Component
    ],
    exports: [
        Comp3Component
    ],

    providers: [],
})
export class Comp3Module { }

And your lazy loading for comp3 should work.

Have you tried specifying the full path for the lazy loaded component?

Below is an example of what we have working (all of our lazy components are housed in the +lazy folder):

{ path: 'lazy', loadChildren: './omfpages/+lazy/lazy.module#LazyModule' }], canActivate: [AuthGuard] }

We use angular cli w/ webpack.

Also - what does your routerLink to the lazy page look like?

Ours:

routerLink: ['omfpages/lazy/page32']   

Note that the "lazy" tag is what hits the main router. App.router then looks up the path to the lazy module and then passes in the "page32" portion to the lazy router.

Below is our lazy router:

...
const routes: Routes = [
  { path: 'page30', component: Page30Component, data: { title: 'Fun     Page'} },
  { path: 'page31/:id', component: Page31Component, data: { title:     'Another Page'} },     // <-- this route requires a param to be passed.
  { path: 'page32', component: Page32Component, data: { title: 'Some Page'} }
];

export const routing: ModuleWithProviders = RouterModule.forChild(routes);

Another way of using loadChildren routing as below:

In your app.route.ts use

// have to be export modules to handle the lazy loading routing
export function loadExampleModuleOne() {  return ExampleModuleOne } 
export function loadExampleModuleTwo() { return ExampleModuleTwo }

then after in your routing you need to use like :

const APP_ROUTE: Routes = [
  {
    path: '',
    redirectTo: 'example-one',
    pathMatch: 'full'
  },
  {
    path: 'example-one',
    loadChildren: loadExampleModuleOne
  },
  {
    path: 'example-two',
    loadChildren: loadExampleModuleTwo
  }
];

export const AppRouting = RouterModule.forRoot(APP_ROUTE);

and then use the AppRouting constant in your app.module.ts like :

import {AppRouting} from './app.routing';


@NgModule({
   import: [
     AppRouting
   ]
})
export class AppModule() {
}

try to change your routes like this const routes: Routes = [

{
    path: '',
    redirectTo: 'home',
    pathMatch: 'full'
}, 
{    
        path: 'home',
    component: HomeComponent
},

 {
    path: 'job-details/:id',
    component: JobDetailsComponent
},

];

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