javascript - Angular 5 with Angular cli non-lazy loading modules in the router - Stack Overflow

Building an angular5 app. The app requires a few alternate layouts.My approach is to handle the high le

Building an angular5 app. The app requires a few alternate layouts.

My approach is to handle the high level routing in the main app module routing file. The said file will map routes to modules. The modules will be lazy loaded for the non-essential speed driven pages and not lazy loaded for the speed critical pages:

app-layout-router.module.ts file:

import {NgModule} from '@angular/core';
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';
import {PublicLayoutModule} from '@modules/layouts/public/public-layout.module';
import {AuthenticatedLayoutModule} from '@modules/layouts/authenticated/authenticated-layout.module';

const routes: Routes = [{
    path: '',
    loadChildren: () => PublicLayoutModule,
},{
    path: 'dashboard',
    loadChildren: () => AuthenticatedLayoutModule,
}];

@NgModule({
    imports: [RouterModule.forRoot(
        routes,
        {
            useHash: false,
            preloadingStrategy: PreloadAllModules
        }
    )],
    exports: [RouterModule],
})

export class AppLayoutRouter {
}

All routes not under dashboard will be pre-rendered for SEO reasons. In the authenticated layout however, I have the option to break the app down by lazy loading the subsequent modules. For example this is the content of the authenticated module router file:

import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {AuthenticatedLayoutComponent} from './authenticated-layoutponent';

const routes: Routes = [{
    path: '',
    ponent: AuthenticatedLayoutComponent,
    children: [{
        path: '',
        loadChildren: '../../dashboard/dashboard.module#DashboardModule'
    }]
}];

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

export class AuthenticatedLayoutRoutingModule {
}

In theory this works, but in practice I hit errors. The expected result is the angular cli webpack will create a chunk for the dashboard module and the app will fetch it via lazy loading. In reality the result is the router cannot load the dashboard module as it thinks the path to the module is not correct.

Here is the error thrown:

Error: Cannot find module '../../dashboard/dashboard.module'.
    at eval (eval at ../../../../../src/$$_lazy_route_resource lazy recursive (main.bundle.js:6), <anonymous>:5:9)
    at ZoneDelegate.invoke (zone.js:388)
    at Object.onInvoke (core.js:4733)
    at ZoneDelegate.invoke (zone.js:387)
    at Zone.run (zone.js:138)
    at eval (zone.js:858)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4724)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at eval (eval at ../../../../../src/$$_lazy_route_resource lazy recursive (main.bundle.js:6), <anonymous>:5:9)
    at ZoneDelegate.invoke (zone.js:388)
    at Object.onInvoke (core.js:4733)
    at ZoneDelegate.invoke (zone.js:387)
    at Zone.run (zone.js:138)
    at eval (zone.js:858)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4724)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at resolvePromise (zone.js:809)
    at resolvePromise (zone.js:775)
    at eval (zone.js:858)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4724)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.invokeTask [as invoke] (zone.js:500)
    at invokeTask (zone.js:1517)
defaultErrorLogger @ core.js:1440
ErrorHandler.handleError @ core.js:1501
next @ core.js:5481
schedulerFn @ core.js:4319
SafeSubscriber.__tryOrUnsub @ Subscriber.js:240
SafeSubscriber.next @ Subscriber.js:187
Subscriber._next @ Subscriber.js:128
Subscriber.next @ Subscriber.js:92
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4299
(anonymous) @ core.js:4755
ZoneDelegate.invoke @ zone.js:388
Zone.run @ zone.js:138
NgZone.runOutsideAngular @ core.js:4681
onHandleError @ core.js:4755
ZoneDelegate.handleError @ zone.js:392
Zone.runGuarded @ zone.js:154
_loop_1 @ zone.js:684
api.microtaskDrainDone @ zone.js:693
drainMicroTaskQueue @ zone.js:602
ZoneTask.invokeTask @ zone.js:500
invokeTask @ zone.js:1517
globalZoneAwareCallback @ zone.js:1543

I can fix this by setting all the module routing to lazy loading (ie lazy load everything)... but I do not want to do this for the public facing pages, eg the login page. I can pre-render the pages just fine, the user will get a pre-rendered index.html file for the login.. but cannot interact with the page till the router has fetched the module from the back-end via lazy loading...

Has anyone else solved this problem? And if so how?

Here is the code in question that fails:

Building an angular5 app. The app requires a few alternate layouts.

My approach is to handle the high level routing in the main app module routing file. The said file will map routes to modules. The modules will be lazy loaded for the non-essential speed driven pages and not lazy loaded for the speed critical pages:

app-layout-router.module.ts file:

import {NgModule} from '@angular/core';
import {PreloadAllModules, RouterModule, Routes} from '@angular/router';
import {PublicLayoutModule} from '@modules/layouts/public/public-layout.module';
import {AuthenticatedLayoutModule} from '@modules/layouts/authenticated/authenticated-layout.module';

const routes: Routes = [{
    path: '',
    loadChildren: () => PublicLayoutModule,
},{
    path: 'dashboard',
    loadChildren: () => AuthenticatedLayoutModule,
}];

@NgModule({
    imports: [RouterModule.forRoot(
        routes,
        {
            useHash: false,
            preloadingStrategy: PreloadAllModules
        }
    )],
    exports: [RouterModule],
})

export class AppLayoutRouter {
}

All routes not under dashboard will be pre-rendered for SEO reasons. In the authenticated layout however, I have the option to break the app down by lazy loading the subsequent modules. For example this is the content of the authenticated module router file:

import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {AuthenticatedLayoutComponent} from './authenticated-layout.ponent';

const routes: Routes = [{
    path: '',
    ponent: AuthenticatedLayoutComponent,
    children: [{
        path: '',
        loadChildren: '../../dashboard/dashboard.module#DashboardModule'
    }]
}];

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

export class AuthenticatedLayoutRoutingModule {
}

In theory this works, but in practice I hit errors. The expected result is the angular cli webpack will create a chunk for the dashboard module and the app will fetch it via lazy loading. In reality the result is the router cannot load the dashboard module as it thinks the path to the module is not correct.

Here is the error thrown:

Error: Cannot find module '../../dashboard/dashboard.module'.
    at eval (eval at ../../../../../src/$$_lazy_route_resource lazy recursive (main.bundle.js:6), <anonymous>:5:9)
    at ZoneDelegate.invoke (zone.js:388)
    at Object.onInvoke (core.js:4733)
    at ZoneDelegate.invoke (zone.js:387)
    at Zone.run (zone.js:138)
    at eval (zone.js:858)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4724)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at eval (eval at ../../../../../src/$$_lazy_route_resource lazy recursive (main.bundle.js:6), <anonymous>:5:9)
    at ZoneDelegate.invoke (zone.js:388)
    at Object.onInvoke (core.js:4733)
    at ZoneDelegate.invoke (zone.js:387)
    at Zone.run (zone.js:138)
    at eval (zone.js:858)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4724)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at resolvePromise (zone.js:809)
    at resolvePromise (zone.js:775)
    at eval (zone.js:858)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4724)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.invokeTask [as invoke] (zone.js:500)
    at invokeTask (zone.js:1517)
defaultErrorLogger @ core.js:1440
ErrorHandler.handleError @ core.js:1501
next @ core.js:5481
schedulerFn @ core.js:4319
SafeSubscriber.__tryOrUnsub @ Subscriber.js:240
SafeSubscriber.next @ Subscriber.js:187
Subscriber._next @ Subscriber.js:128
Subscriber.next @ Subscriber.js:92
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4299
(anonymous) @ core.js:4755
ZoneDelegate.invoke @ zone.js:388
Zone.run @ zone.js:138
NgZone.runOutsideAngular @ core.js:4681
onHandleError @ core.js:4755
ZoneDelegate.handleError @ zone.js:392
Zone.runGuarded @ zone.js:154
_loop_1 @ zone.js:684
api.microtaskDrainDone @ zone.js:693
drainMicroTaskQueue @ zone.js:602
ZoneTask.invokeTask @ zone.js:500
invokeTask @ zone.js:1517
globalZoneAwareCallback @ zone.js:1543

I can fix this by setting all the module routing to lazy loading (ie lazy load everything)... but I do not want to do this for the public facing pages, eg the login page. I can pre-render the pages just fine, the user will get a pre-rendered index.html file for the login.. but cannot interact with the page till the router has fetched the module from the back-end via lazy loading...

Has anyone else solved this problem? And if so how?

Here is the code in question that fails: https://github./jdcrecur/ang5ModuleRouting

Share Improve this question edited Jan 31, 2018 at 18:36 asked Jan 30, 2018 at 14:08 user1037355user1037355 7
  • What kind of error are you getting? Can you please post the error. Tnx – joel Commented Jan 30, 2018 at 16:48
  • Error added to the post – user1037355 Commented Jan 30, 2018 at 18:38
  • If you set the loadChildren path relative to the app root such as loadChildren: 'app/dashboard/dashboard.module#DashboardModule', does that change anything? – Alexander Staroselsky Commented Jan 30, 2018 at 18:43
  • Same error but with the new path: core.js:1440 ERROR Error: Uncaught (in promise): Error: Cannot find module 'app/modules/page/dashboard/dashboard.module'. – user1037355 Commented Jan 30, 2018 at 18:48
  • I have posted the code to github if anyone is interested: github./jdcrecur/ang5ModuleRouting – user1037355 Commented Jan 30, 2018 at 18:52
 |  Show 2 more ments

1 Answer 1

Reset to default 3

I'm experiencing the same issue. This could be a bug with the angular-cli. I'm still not sure whether the bug is in the cli or in our code!

As mentioned by Gerrit on the other question here it's still possible to pile with aot: ng serve --aot

I've also resolved the issue by downgrading my angular-cli as mentioned on github from 1.7.2 to 1.6.8, which is the last CLI-Version which seems to work in our case.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745430482a4627366.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信