Search code examples
angulartypescriptangular-routingangular-moduleangular-load-children

What is difference between `loadChildren: () => import('./hoge.module.ts).then(m => m.HogeModule)' and loadChildren: './hoge.module#HogeModule'?


Issue

We get an error cannot find module in case following structure.

app-routing.module.ts

const routes: Routes = [
  {
    path: CHILD_MANAGEMENT_PORTAL.baseUrl,
    canActivate: [AuthGuard],
    component: EnvelopeComponent,
    loadChildren: () =>
      import('./features/child-management/child-management.module').then(
        m => m.ChildManagementModule
      ),
    data: {
      menuResolver: ChildManagementMenuResolver,
      pageTitleResolver: ChildManagementPageTitleResolver,
      portalData: CHILD_MANAGEMENT_PORTAL
    }
  },
];

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

child-management-routing.module.ts : wrong

const routes: Routes = [
  {
    path: 'dashboard',
    loadChildren: './dashboard/child-dashboard.module#ChildDashboardModule'
  },
  {
    path: '**',
    redirectTo: 'dashboard'
  }
];

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

We could solve this error by only changing loadChildren of child routing.module from loadChildren: './hoge.module#HogeModule' to loadChildren: () => import('./hoge.module.ts).then(m => m.HogeModule)'.

child-management-routing.module.ts : correct

const routes: Routes = [
  {
    path: 'dashboard',
    loadChildren: () => import('./dashboard/child-dashboard.module').then(m => m.ChildDashboardModule)
  },
  {
    path: '**',
    redirectTo: 'dashboard'
  }
];

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

But I could not understand why. (I did not change app-routing.module.ts...)

So could you explain the difference?


Solution

  • It seems like you upgraded from Angular 7.x to 8.x and this is where the scheme changed.

    Explanation (From angular docs)

    When Angular first introduced lazy routes, there wasn't browser support for dynamically loading additional JavaScript. Angular created our own scheme using the syntax loadChildren: './lazy/lazy.module#LazyModule' and built tooling to support it. Now that ECMAScript dynamic import is supported in many browsers, Angular is moving toward this new syntax.

    In version 8, the string syntax for the loadChildren route specification was deprecated, in favor of new syntax that uses import() syntax.

    Before

    const routes: Routes = [{
      path: 'lazy',
      // The following string syntax for loadChildren is deprecated
      loadChildren: './lazy/lazy.module#LazyModule'
    }];
    

    After

    const routes: Routes = [{
      path: 'lazy',
      // The new import() syntax
       loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
    }];
    

    Hope this helps you out.