问题描述
构建angular5应用。该应用程序需要一些备用布局。
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 {
}
所有不在仪表板下的路线都会因SEO原因而预先呈现。但是,在经过身份验证的布局中,我可以选择通过延迟加载后续模块来中断应用程序。例如,这是经过身份验证的模块路由器文件的内容:
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.component';
const routes: Routes = [{
path: '',
component: AuthenticatedLayoutComponent,
children: [{
path: '',
loadChildren: '../../dashboard/dashboard.module#DashboardModule'
}]
}];
@NgModule({
imports: [RouterModule.forChild(
routes
)],
exports: [RouterModule],
})
export class AuthenticatedLayoutRoutingModule {
}
理论上这有效,但实际上我遇到了错误。预期的结果是角度cli webpack将为仪表板模块创建一个块,应用程序将通过延迟加载来获取它。实际上,结果是路由器无法加载仪表板模块,因为它认为模块的路径不正确。
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.
以下是抛出的错误:
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
我可以通过将所有模块路由设置为延迟加载来解决此问题(即延迟加载所有内容)...但我不想为面向公众的页面(例如登录页面)执行此操作。我可以预先渲染页面,用户将获得一个预先渲染的index.html文件用于登录..但是无法与页面交互,直到路由器通过延迟加载从后端获取模块。 。
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.com/jdcrecur/ang5ModuleRouting
推荐答案
我遇到了同样的问题。这可能是angular-cli的错误。我仍然不确定错误是在cli中还是在我们的代码中!
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!
如关于另一个问题仍然可以用aot编译: ng serve --aot
As mentioned by Gerrit on the other question here it's still possible to compile with aot: ng serve --aot
我也通过降低我的角度cli来解决这个问题,如从 1.7.2 到 1.6.8 ,这是最后一个似乎适用于我们案例的CLI版本。
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.
这篇关于Angular 5与路由器中的Angular cli非延迟加载模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!