Angular 4通用延迟加载错误

时间:2017-06-14 11:38:57

标签: javascript angular angular-universal

我已经设置了一个新的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}`);
});

我很高兴通用工作正常,但每次刷新都会收到此错误信息。

2 个答案:

答案 0 :(得分:0)

Angular AOT CLI延迟加载与服务器端呈现存在问题。服务器不知道&#34;系统&#34;这是角度的默认加载器。因此,在这种情况下,需要添加angular2-template-loader&#39; angular2-router-loader&#39;通过webpack配置在服务器端加载模板。

答案 1 :(得分:0)

目前不支持使用CLI的捆绑器进行延迟加载,请参阅here。它计划在即将发布的版本中进行,并且正在积极开发中,所以在此期间请紧紧抓住。