我已经设置了一个新的Angular CLI项目,以了解如何使用Angular Universal启用服务器端渲染。
我已经设置好了,一切都运行良好,但我决定懒加载一个名为'lazy'的模块。
我这样做,当使用ng serve
时它可以工作,但是当Universal运行时(使用AOT),当我进入懒惰路径并刷新页面时,我得到了这个错误,尽管我看到了懒惰的组件浏览器:
ERROR { Error: Uncaught (in promise): ReferenceError: System is not defined
ReferenceError: System is not defined
at SystemJsNgModuleLoader.loadFactory (C:\Users\shachar\Desktop\universal\packages\core\src\linker\system_js_ng_module_factory_loader.ts:67:1)
at SystemJsNgModuleLoader.load (C:\Users\shachar\Desktop\universal\node_modules\@angular\core\bundles\core.umd.js:5724:35)
at RouterConfigLoader.loadModuleFactory (C:\Users\shachar\Desktop\universal\packages\router\src\router_config_loader.ts:71:1)
at RouterConfigLoader.load (C:\Users\shachar\Desktop\universal\node_modules\@angular\router\bundles\router.umd.js:3402:52)
at MergeMapSubscriber.project (C:\Users\shachar\Desktop\universal\node_modules\@angular\router\bundles\router.umd.js:1570:74)
at MergeMapSubscriber._tryNext (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\operator\mergeMap.ts:125:21)
at MergeMapSubscriber._next (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\operator\mergeMap.ts:115:12)
at MergeMapSubscriber.Subscriber.next (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\Subscriber.ts:95:12)
at ScalarObservable._subscribe (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\observable\ScalarObservable.ts:51:18)
at ScalarObservable.Observable._trySubscribe (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\Observable.ts:113:19)
at resolvePromise (C:\Users\shachar\Desktop\universal\node_modules\zone.js\dist\zone-node.js:770:31)
at resolvePromise (C:\Users\shachar\Desktop\universal\node_modules\zone.js\dist\zone-node.js:741:17)
at C:\Users\shachar\Desktop\universal\node_modules\zone.js\dist\zone-node.js:818:17
at ZoneDelegate.invokeTask (C:\Users\shachar\Desktop\universal\node_modules\zone.js\dist\zone-node.js:424:31)
at Object.onInvokeTask (C:\Users\shachar\Desktop\universal\packages\core\src\zone\ng_zone.ts:257:1)
at ZoneDelegate.invokeTask (C:\Users\shachar\Desktop\universal\node_modules\zone.js\dist\zone-node.js:423:36)
at Zone.runTask (C:\Users\shachar\Desktop\universal\node_modules\zone.js\dist\zone-node.js:191:47)
at drainMicroTaskQueue (C:\Users\shachar\Desktop\universal\node_modules\zone.js\dist\zone-node.js:584:35)
at Server.ZoneTask.invoke (C:\Users\shachar\Desktop\universal\node_modules\zone.js\dist\zone-node.js:490:25)
at emitTwo (events.js:106:13)
rejection:
{ ReferenceError: System is not defined
at SystemJsNgModuleLoader.loadFactory (C:\Users\shachar\Desktop\universal\packages\core\src\linker\system_js_ng_module_factory_loader.ts:67:1)
at SystemJsNgModuleLoader.load (C:\Users\shachar\Desktop\universal\node_modules\@angular\core\bundles\core.umd.js:5724:35)
at RouterConfigLoader.loadModuleFactory (C:\Users\shachar\Desktop\universal\packages\router\src\router_config_loader.ts:71:1)
at RouterConfigLoader.load (C:\Users\shachar\Desktop\universal\node_modules\@angular\router\bundles\router.umd.js:3402:52)
at MergeMapSubscriber.project (C:\Users\shachar\Desktop\universal\node_modules\@angular\router\bundles\router.umd.js:1570:74)
at MergeMapSubscriber._tryNext (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\operator\mergeMap.ts:125:21)
at MergeMapSubscriber._next (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\operator\mergeMap.ts:115:12)
at MergeMapSubscriber.Subscriber.next (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\Subscriber.ts:95:12)
at ScalarObservable._subscribe (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\observable\ScalarObservable.ts:51:18)
at ScalarObservable.Observable._trySubscribe (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\Observable.ts:113:19)
__zone_symbol__currentTask:
ZoneTask {
_zone: [Object],
runCount: 0,
_zoneDelegates: null,
_state: 'notScheduled',
type: 'microTask',
source: 'Promise.then',
data: undefined,
scheduleFn: undefined,
cancelFn: null,
callback: [Function],
invoke: [Function] } },
promise:
ZoneAwarePromise {
__zone_symbol__state: 0,
__zone_symbol__value:
{ ReferenceError: System is not defined
at SystemJsNgModuleLoader.loadFactory (C:\Users\shachar\Desktop\universal\packages\core\src\linker\system_js_ng_module_factory_loader.ts:67:1)
at SystemJsNgModuleLoader.load (C:\Users\shachar\Desktop\universal\node_modules\@angular\core\bundles\core.umd.js:5724:35)
at RouterConfigLoader.loadModuleFactory (C:\Users\shachar\Desktop\universal\packages\router\src\router_config_loader.ts:71:1)
at RouterConfigLoader.load (C:\Users\shachar\Desktop\universal\node_modules\@angular\router\bundles\router.umd.js:3402:52)
at MergeMapSubscriber.project (C:\Users\shachar\Desktop\universal\node_modules\@angular\router\bundles\router.umd.js:1570:74)
at MergeMapSubscriber._tryNext (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\operator\mergeMap.ts:125:21)
at MergeMapSubscriber._next (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\operator\mergeMap.ts:115:12)
at MergeMapSubscriber.Subscriber.next (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\Subscriber.ts:95:12)
at ScalarObservable._subscribe (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\observable\ScalarObservable.ts:51:18)
at ScalarObservable.Observable._trySubscribe (C:\Users\shachar\Desktop\universal\node_modules\rxjs\src\Observable.ts:113:19) __zone_symbol__currentTask: [Object] } },
zone:
Zone {
_properties: { isAngularZone: true },
_parent:
Zone {
_properties: {},
_parent: null,
_name: '<root>',
_zoneDelegate: [Object] },
_name: 'angular',
_zoneDelegate:
ZoneDelegate {
_taskCounts: [Object],
zone: [Circular],
_parentDelegate: [Object],
_forkZS: null,
_forkDlgt: null,
_forkCurrZone: [Object],
_interceptZS: null,
_interceptDlgt: null,
_interceptCurrZone: [Object],
_invokeZS: [Object],
_invokeDlgt: [Object],
_invokeCurrZone: [Circular],
_handleErrorZS: [Object],
_handleErrorDlgt: [Object],
_handleErrorCurrZone: [Circular],
_scheduleTaskZS: [Object],
_scheduleTaskDlgt: [Object],
_scheduleTaskCurrZone: [Circular],
_invokeTaskZS: [Object],
_invokeTaskDlgt: [Object],
_invokeTaskCurrZone: [Circular],
_cancelTaskZS: [Object],
_cancelTaskDlgt: [Object],
_cancelTaskCurrZone: [Circular],
_hasTaskZS: [Object],
_hasTaskDlgt: [Object],
_hasTaskDlgtOwner: [Circular],
_hasTaskCurrZone: [Circular] } },
task:
ZoneTask {
_zone:
Zone {
_properties: [Object],
_parent: [Object],
_name: 'angular',
_zoneDelegate: [Object] },
runCount: 0,
_zoneDelegates: null,
_state: 'notScheduled',
type: 'microTask',
source: 'Promise.then',
data: undefined,
scheduleFn: undefined,
cancelFn: null,
callback: [Function],
invoke: [Function] } }
不,我根本不使用SystemJS。
app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { APP_BASE_HREF } from '@angular/common';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { LazyModule } from './lazy/lazy.module';
import { HomeComponent } from './home/home.component';
@NgModule({
declarations: [
AppComponent,
HomeComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'universal' }),
RouterModule.forRoot([
{
path: '',
component: HomeComponent
},
{
path: 'lazy',
loadChildren: './lazy/lazy.module#LazyModule'
}
])
],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }],
bootstrap: [AppComponent]
})
export class AppModule { }
lazy.module.ts:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { LazyComponent } from './lazy.component';
@NgModule({
imports: [
CommonModule,
RouterModule.forChild([
{ path: '', component: LazyComponent }
])
],
declarations: [LazyComponent]
})
export class LazyModule { }
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
ServerModule,
AppModule
],
bootstrap: [AppComponent]
})
export class AppServerModule { }
server.ts :(快递)
import 'reflect-metadata';
import 'zone.js/dist/zone-node';
import * as Express from 'express';
import { join } from 'path';
import { readFileSync } from 'fs';
import { renderModuleFactory } from '@angular/platform-server';
import { enableProdMode } from '@angular/core';
const { AppServerModuleNgFactory } = require('../dist/ngfactory/src/app/app.server.module.ngfactory');
const app = Express();
enableProdMode();
const PORT = 4000;
const template = readFileSync(join(__dirname, '..', 'dist', 'index.html')).toString();
app.engine('html', (_, options, callback) => {
const opts = { document: template, url: options.req.url };
renderModuleFactory(AppServerModuleNgFactory, opts)
.then(html => callback(null, html));
});
app.set('views', join(__dirname, '..', 'dist'));
app.set('view engine', 'html');
app.get('*.*', Express.static(join(__dirname, '..', 'dist')));
app.get('*', (req, res) => {
res.render('index', { req });
});
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}`);
});
我很高兴通用工作正常,但每次刷新都会收到此错误信息。
答案 0 :(得分:0)
Angular AOT CLI延迟加载与服务器端呈现存在问题。服务器不知道&#34;系统&#34;这是角度的默认加载器。因此,在这种情况下,需要添加angular2-template-loader&#39; angular2-router-loader&#39;通过webpack配置在服务器端加载模板。
答案 1 :(得分:0)
目前不支持使用CLI的捆绑器进行延迟加载,请参阅here。它计划在即将发布的版本中进行,并且正在积极开发中,所以在此期间请紧紧抓住。