Angular 服务器端呈现无限加载无响应

Angular Server Side Rendering Infinit loading no response

我正在训练使用本教程添加 Angular 服务器端重新渲染: https://angular.io/guide/universal

我正在使用 i18n 翻译 + material + firebase。

最初我不得不更改 server.ts 文件以指向正确的目录 (dist/browser/it) 因为错误:

 Error: Failed to lookup view "index" in views directory "C:\Data\Development\Web\Wor
kingHours4bWeb\dist\WorkingHours4bWeb\browser"
    at Function.render (C:\Data\Development\Web\WorkingHours4bWeb\dist\WorkingHours4
bWeb\server\main.js:128813:17)
    at ServerResponse.render (C:\Data\Development\Web\WorkingHours4bWeb\dist\Working
Hours4bWeb\server\main.js:244414:7)
    at C:\Data\Development\Web\WorkingHours4bWeb\dist\WorkingHours4bWeb\server\main.
js:373787:13
    at Layer.handle [as handle_request] (C:\Data\Development\Web\WorkingHours4bWeb\d
ist\WorkingHours4bWeb\server\main.js:180406:5)
    at next (C:\Data\Development\Web\WorkingHours4bWeb\dist\WorkingHours4bWeb\server
\main.js:133160:13)
    at Route.dispatch (C:\Data\Development\Web\WorkingHours4bWeb\dist\WorkingHours4b
Web\server\main.js:133135:3)
    at Layer.handle [as handle_request] (C:\Data\Development\Web\WorkingHours4bWeb\d
ist\WorkingHours4bWeb\server\main.js:180406:5)
    at C:\Data\Development\Web\WorkingHours4bWeb\dist\WorkingHours4bWeb\server\main.
js:413002:22
    at param (C:\Data\Development\Web\WorkingHours4bWeb\dist\WorkingHours4bWeb\serve
r\main.js:413075:14)
    at param (C:\Data\Development\Web\WorkingHours4bWeb\dist\WorkingHours4bWeb\serve
r\main.js:413086:14)

现在我的选项卡正在加载但没有给出任何结果,调试器没有错误,只加载了无限时间而没有页面结果。我也尝试调试命令 npm run dev:ssr 但我没有任何错误。

(加载中)

这是我的 package.json:

{
  "name": "working-hours4b-web",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "start0000": "ng serve --host 0.0.0.0 --disable-host-check",
    "dev:ssr": "ng run WorkingHours4bWeb:serve-ssr",
    "serve:ssr": "node dist/WorkingHours4bWeb/server/main.js",
    "build:ssr": "ng build --prod && ng run WorkingHours4bWeb:server:production",
    "prerender": "ng run WorkingHours4bWeb:prerender"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~11.0.5",
    "@angular/cdk": "^11.0.3",
    "@angular/common": "~11.0.5",
    "@angular/compiler": "~11.0.5",
    "@angular/core": "~11.0.5",
    "@angular/fire": "^6.1.4",
    "@angular/flex-layout": "^11.0.0-beta.33",
    "@angular/forms": "~11.0.5",
    "@angular/http": "^7.2.16",
    "@angular/localize": "~11.0.5",
    "@angular/material": "^11.0.3",
    "@angular/platform-browser": "~11.0.5",
    "@angular/platform-browser-dynamic": "~11.0.5",
    "@angular/platform-server": "~11.0.5",
    "@angular/router": "~11.0.5",
    "@js-joda/core": "^3.2.0",
    "@js-joda/extra": "^0.4.0",
    "@js-joda/locale": "^3.2.2",
    "@ng-bootstrap/ng-bootstrap": "^8.0.0",
    "@nguniversal/express-engine": "^11.1.2",
    "bootstrap": "^4.5.0",
    "chart.js": "^2.9.4",
    "chartjs-plugin-datalabels": "^0.7.0",
    "date-fns": "^2.16.1",
    "express": "^4.15.2",
    "firebase": "^8.2.1",
    "lodash": "^4.17.20",
    "materialize-angular": "^0.7.10",
    "materialize-css": "^1.0.0",
    "ng-inline-svg": "^11.0.1",
    "ng2-charts": "^2.4.2",
    "ngx-color-picker": "^11.0.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "uuid": "^8.3.2",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1100.5",
    "@angular/cli": "~11.0.5",
    "@angular/compiler-cli": "~11.0.5",
    "@nguniversal/builders": "^11.0.1",
    "@types/express": "^4.17.0",
    "@types/jasmine": "~3.6.0",
    "@types/node": "^12.11.1",
    "@typescript-eslint/eslint-plugin": "^4.11.1",
    "@typescript-eslint/parser": "^4.11.1",
    "codelyzer": "^6.0.0",
    "eslint": "^7.16.0",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-plugin-import": "^2.22.1",
    "jasmine-core": "~3.6.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~5.1.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "typescript": "~4.0.2"
  }
}

是否有任何解决方案可以查看确切的错误?

短篇小说

这很可能与 Firebase 有关。尝试:

  • 使用take(1) 或一些类似操作限制valueChanges() 的使用。 出于测试目的,您可以将对 firebase 的整个调用替换为 returns 可观察到的模拟调用或立即完成的承诺。如果有效,则说明您的问题出在对数据库的调用上。
  • 使用不同版本的 firebase@angular/fire

说来话长

为什么要限制 valueChanges()

Angular Universal 在服务器上运行您的代码。如果您的代码生成任何永远不会完成的异步操作或可观察对象,您的服务器将在等待操作完成时永远挂起。

valueChanges() 在客户端上是必需的,以拥有“实时”流并将数据库更改实时反映到 UI。然而,在服务器上,这种行为与您的需要相反,因为您可能想要获取一些数据并呈现页面。

您的代码应该检测它是 运行 在浏览器上还是在服务器上,并创建适当的可观察对象(一个在服务器第一次发射 后完成 的对象,一个对浏览器保持打开状态)。

NOTE valueChanges() is a common problem in this case, but the same concept applies to any other observable you might have subscribed to in your code.

TIP You could use UniversalService from the @bespunky/angular-zen library. Just install the library and inject the service where you need it.

为什么要尝试不同的版本?

在某些时候,@angular/fire 的一个版本存在一个错误,即库在内部留下未完成的操作,进而导致无法完成 NgZone 任务。

解决方案是升级或降级,但您必须找到匹配的 firebase 版本。