javascript - Angular 4 通用延迟加载错误

标签 javascript angular angular-universal

我已经建立了一个新的 Angular CLI 项目来学习如何使用 Angular Universal 启用服务器端渲染。

我已经设置完毕,一切都运行良好,但我决定延迟加载一个名为“lazy”的模块。

我这样做了,当使用 ngserve 时它可以工作,但是当 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}`);
});

我很高兴通用功能可以正常工作,但每次刷新时都会收到此错误消息,这很糟糕。

最佳答案

服务器端渲染的 Angular AOT CLI 延迟加载存在问题。服务器不知道“系统”,它是 Angular 默认加载器。因此,在这种情况下,需要添加 angular2-template-loader' 和 'angular2-router-loader' 以便通过 webpack 配置在服务器端加载模板。

关于javascript - Angular 4 通用延迟加载错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44543732/

相关文章:

javascript - 布局中滚动条位置错误 : fit

javascript - XML 文档和 XML 字符串有什么区别?

angular - 有没有办法在 Angular4 中链接 @Injectable()

Angular Universal SSR : dev and build work, 服务没有

angular - service worker 和 sw precache with angular universal

具有来自 Web 服务的动态元数据的 Angular 6 元服务

javascript - 如何为 AngularJS 应用程序定义两种模式(夜间/白天)

javascript - 使用 JavaScript 更改一组元素的样式

javascript - 如何解决错误:接近堆限制的无效标记压缩分配失败-应用程序中的JavaScript堆内存不足

angular 将输入传递给 ng-content 中的子组件