Angular Universal:如何解决缺少的名称、模块和其他奇怪的事情

Posted

技术标签:

【中文标题】Angular Universal:如何解决缺少的名称、模块和其他奇怪的事情【英文标题】:Angular Universal : How to resolve missing names, modules and other weird things 【发布时间】:2018-09-03 11:49:32 【问题描述】:

在主应用程序中一切正常,但尝试提供捆绑的 s-s-r 会产生我不明白的错误。我将在下面发布有关设置的所有内容。

有太多的小碎片,到处都是,我希望生产服务器端应用程序的过程会随着时间的推移而改进。

此外,我对这个设置的某些部分不太有信心,因为我仍在努力掌握这一点,任何改进建议都将不胜感激,谢谢。

功能:json 包


  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": 
    "lint": "eslint .",
    "serve": "firebase serve --only functions",
    "shell": "firebase experimental:functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  ,
  "dependencies": 
    "firebase-admin": "~5.10.0",
    "firebase-functions": "^0.9.0",
    "@angular/animations": "^5.2.9",
    "@angular/cdk": "^5.2.4",
    "@angular/common": "^5.2.9",
    "@angular/compiler": "^5.2.9",
    "@angular/core": "^5.2.9",
    "@angular/forms": "^5.2.9",
    "@angular/http": "^5.2.9",
    "@angular/material": "^2.0.0-beta.10",
    "@angular/platform-browser": "^5.2.9",
    "@angular/platform-browser-dynamic": "^5.2.9",
    "@angular/platform-server": "^5.2.9",
    "@angular/router": "^5.2.9",
    "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.5",
    "@nguniversal/express-engine": "^5.0.0-beta.7",
    "@nguniversal/module-map-ngfactory-loader": "^5.0.0-beta.7",
    "@types/lodash": "^4.14.74",
    "angularfire2": "^4.0.0-rc0",
    "bootstrap": "^4.0.0-beta",
    "core-js": "^2.5.1",
    "firebase": "^4.3.1",
    "hammerjs": "^2.0.8",
    "jquery": "^3.2.1",
    "jquery-ui": "^1.12.1",
    "lodash": "^4.17.5",
    "rxjs": "^5.4.3",
    "scss": "^0.2.4",
    "ts-loader": "^4.1.0",
    "zone.js": "^0.8.17",
    "express": "^4.15.4"
  ,
  "devDependencies": 
    "@angular/cli": "^1.7.3",
    "@angular/compiler-cli": "^5.2.9",
    "@angular/language-service": "^4.4.3",
    "@types/bootstrap": "^3.3.36",
    "@types/core-js": "^0.9.46",
    "@types/jasmine": "^2.6.0",
    "@types/jasminewd2": "^2.0.3",
    "@types/jquery": "^3.2.12",
    "@types/node": "^6.0.88",
    "angular-universal-express-firebase": "0.0.4",
    "codelyzer": "~3.0.1",
    "eslint-plugin-promise": "^3.6.0",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "^1.7.1",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "node-sass": "^4.5.3",
    "protractor": "~5.1.2",
    "ts-node": "~3.0.4",
    "tslint": "~5.3.2",
    "typescript": "^2.7.2"
  ,
  "private": true

服务器功能

import 'zone.js/dist/zone-node';
import * as functions from 'firebase-functions';
import * as express from 'express';
import  renderModuleFactory  from '@angular/platform-server';
import * as fs from 'fs';

const document = fs.readFileSync(__dirname + '/index.html', 'utf8');
const AppServerModuleNgFactory = require(__dirname + '/dist-server/main.bundle');

const app = express();

app.get('**', (req, res) => 
    const url = req.path;
    renderModuleFactory(AppServerModuleNgFactory,  document, url )
        .then(html => 
            res.set('Cache-Control', 'public, max-age=600');
            res.send(html);
        );
);

export let s-s-rapp = functions.https.onRequest(app);

服务器 TS 配置


    "compileOnSave": false,
    "compilerOptions": 
        "outDir": "../",
        "rootDir": ".",
        "sourceMap": true,
        "declaration": false,
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "target": "es5",
        "typeRoots": [
            "node_modules/@types"
        ],
        "lib": [
            "es2016",
            "dom"
        ]
    ,
    "files": [
        "index.ts"
    ]

我用firebase serve --only functions服务,服务后我得到不同类型的错误,修复后会出现另一个错误。

到目前为止,我一直坚持这一点。

TypeError: 无法读取未定义的属性“名称”

at ...functions/node_modules/@angular/core/bundles/core.umd.js:5528:146
at ZoneDelegate.invoke (...functions/node_modules/zone.js/dist/zone-node.js:388:26)
at Object.onInvoke (.../functions/node_modules/@angular/core/bundles/core.umd.js:4787:33)
at ZoneDelegate.invoke (.../functions/node_modules/zone.js/dist/zone-node.js:387:32)
at Zone.run (.../functions/node_modules/zone.js/dist/zone-node.js:138:43)
at NgZone.run (.../functions/node_modules/@angular/core/bundles/core.umd.js:4604:69)
at PlatformRef.bootstrapModuleFactory (.../functions/node_modules/@angular/core/bundles/core.umd.js:5527:23)
at Object.renderModuleFactory (.../functions/node_modules/@angular/platform-server/bundles/platform-server.umd.js:1815:39)
at .../functions/index.js:13:23
at Layer.handle [as handle_request] (.../functions/node_modules/express/lib/router/layer.js:95:5)

起源应用程序:

包 JSON


  "name": "my app",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": 
    "ng": "ng",
    "start": "ng serve --host 0.0.0.0",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  ,
  "private": true,
  "dependencies": 
    "@angular/animations": "^5.2.9",
    "@angular/cdk": "^2.0.0-beta.10",
    "@angular/common": "^5.2.9",
    "@angular/compiler": "^5.2.9",
    "@angular/core": "^5.2.9",
    "@angular/forms": "^5.2.9",
    "@angular/http": "^5.2.9",
    "@angular/material": "^2.0.0-beta.10",
    "@angular/platform-browser": "^5.2.9",
    "@angular/platform-browser-dynamic": "^5.2.9",
    "@angular/platform-server": "^5.2.9",
    "@angular/router": "^5.2.9",
    "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.5",
    "@nguniversal/express-engine": "^5.0.0-beta.7",
    "@nguniversal/module-map-ngfactory-loader": "^5.0.0-beta.7",
    "@types/lodash": "^4.14.74",
    "angularfire2": "^4.0.0-rc0",
    "bootstrap": "^4.0.0-beta",
    "core-js": "^2.5.1",
    "firebase": "^4.3.1",
    "hammerjs": "^2.0.8",
    "jquery": "^3.2.1",
    "jquery-ui": "^1.12.1",
    "lodash": "^4.17.5",
    "rxjs": "^5.4.3",
    "scss": "^0.2.4",
    "ts-loader": "^4.1.0",
    "zone.js": "^0.8.17"
  ,
  "devDependencies": 
    "@angular/cli": "^1.7.3",
    "@angular/compiler-cli": "^5.2.9",
    "@angular/language-service": "^4.4.3",
    "@types/bootstrap": "^3.3.36",
    "@types/jasmine": "^2.6.0",
    "@types/jasminewd2": "^2.0.3",
    "@types/jquery": "^3.2.12",
    "@types/node": "^6.0.88",
    "angular-universal-express-firebase": "0.0.4",
    "codelyzer": "~3.0.1",
    "jasmine-core": "~2.6.2",
    "jasmine-spec-reporter": "~4.1.0",
    "karma": "^1.7.1",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "node-sass": "^4.5.3",
    "protractor": "~5.1.2",
    "ts-node": "~3.0.4",
    "tslint": "~5.3.2",
    "typescript": "^2.6.2"
  

TSCONFIG


  "compileOnSave": false,
  "compilerOptions": 
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2016",
      "dom"
    ]
  

TSCONFIG.SERVER.JSON


    "extends": "../tsconfig.json",
    "compilerOptions": 
        "outDir": "../out/-tsc/app",
        "baseUrl": ".",
        "module": "commonjs",
        "types": []
    ,
    "exclude": [
        "test.ts",
        "**/*.spec.ts"
    ],
    "angularCompileOptions": 
        "entryModule": "app/app.server.module#AppServerModule"
    

APP.SERVER.MODULE.TS

import  NgModule  from '@angular/core';
import  ServerModule  from '@angular/platform-server';

import  AppModule  from './app.module';
import  AppComponent  from './app.component';

@NgModule(
    imports: [AppModule, ServerModule],
    bootstrap: [AppComponent]
)
export class AppServerModule  

APP.MODULE.TS

import  BrowserAnimationsModule  from '@angular/platform-browser/animations';
import  HttpModule  from '@angular/http';
import  BrowserModule  from '@angular/platform-browser';
import  NgModule, CUSTOM_ELEMENTS_SCHEMA  from '@angular/core';
import  AppComponent  from './app.component';
import  AngularFireModule  from 'angularfire2';
import  RouterModule, Routes  from '@angular/router';
import  AppRoutingModule  from './app-routing.module';
import  environment  from '../environments/environment';
import  AngularFireDatabaseModule  from 'angularfire2/database';
import  AngularFireAuthModule  from 'angularfire2/auth';
import  DataService  from './dataservice';
import  HomeComponent  from './home/home.component';
import  FormsModule  from '@angular/forms';
import  Location, LocationStrategy, PathLocationStrategy  from '@angular/common';
import  NgbModule  from '@ng-bootstrap/ng-bootstrap';
import  CommonModule  from '@angular/common';
import 
  MdDialog, MaterialModule, MdButtonModule, MdCardModule, MdToolbarModule, MdInputModule,
  MdMenuModule, MdIconModule, MdProgressBarModule, MdRadioModule, MdDialogModule, MdSelectModule, MdTabsModule,
  MdSnackBarModule, MdProgressSpinnerModule, MdTooltipModule
 from '@angular/material';

import  PostsUtilComponent  from './utils/postsUtil';
import  FeaturesComponent  from './features/features.component';
import  MediaPlayerService  from './utils/mediaPlayerService';
import  HomeUtils  from './home/homeUtils';
import  DownloadComponent  from './download/download.component';
import  PostComponent  from './post/post.component';
import  NodesComponent  from './utils/nodes';
import  PostFactory  from './utils/postFactory';
import  TestServerFunctionComponent  from './utils/testServerFunction';

const appRoutes: Routes = [
   path: '', component: HomeComponent ,
   path: 'home', component: HomeComponent ,
   path: 'projects', component: HomeComponent ,
   path: 'features', component: FeaturesComponent ,
   path: 'download', component: DownloadComponent ,
   path: 'post', component: PostComponent ,

];
@NgModule(
  imports: [
    CommonModule,
    BrowserModule.withServerTransition( appId: 'serverside' ),
    RouterModule.forRoot(appRoutes),
    NgbModule.forRoot(),
    AppRoutingModule,
    FormsModule,
    HttpModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireDatabaseModule,
    AngularFireAuthModule,
    BrowserAnimationsModule,
    MdDialogModule,
    MdButtonModule,
    MdCardModule,
    MdMenuModule,
    MdToolbarModule,
    MdIconModule,
    MdProgressBarModule,
    MdInputModule,
    MdRadioModule,
    MdSelectModule,
    MdTabsModule,
    MdSnackBarModule,
    MdProgressSpinnerModule,
    MdTooltipModule
  ],
  providers: [DataService, PostsUtilComponent, NodesComponent, PostFactory, MediaPlayerService,
    HomeUtils, TestServerFunctionComponent],
  declarations: [AppComponent, HomeComponent, FeaturesComponent, DownloadComponent, PostComponent],
  entryComponents: [],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  bootstrap: [AppComponent]
)
export class AppModule  

MAIN.TS

import  enableProdMode  from '@angular/core';
import  platformBrowserDynamic  from '@angular/platform-browser-dynamic';

import  AppModule  from './app/app.module';
import  environment  from './environments/environment';
import 'hammerjs';

if (environment.production) 
  enableProdMode();


platformBrowserDynamic().bootstrapModule(AppModule);

MAIN.SERVER.TS

export  AppServerModule  from './app/app.server.module';

【问题讨论】:

你有延迟加载的模块吗? 【参考方案1】:

解决方案:

    使用 npm run build --prod --aot 您的组件中可能有一个 name 变量,但您没有对其初始化任何值(例如:public name: any = "title";)

【讨论】:

--aot 默认开启。 @Relm 这实际上取决于他们运行的版本,默认情况下它并不总是打开,并且由于他们运行的是旧版本的@angular/materials(仍然使用 md 而不是 mat ),默认情况下他们可能没有 aot @JooBeck,我的评论是在这个问题的上下文中。【参考方案2】:

我的猜测是你得到的“未定义错误”是因为在服务器上你不能使用浏览器对象(窗口、文档、导航器)。 见:https://github.com/angular/universal 您可以尝试以下方法:

在您的 AppModule 中包含 BrowserAnimationsModule。移除此模块。 在 ServerModule 中包含 NoopAnimationsModule。 (所以你不 由于缺少动画而出现错误) 创建一个包含 BrowserAnimationsModule 的新 BrowserModule 和 AppModule。 BrowserModule 也应该引导 应用组件。 在您的 main.ts 中引导新的 BrowserModule。

我希望这可以帮助您解决问题。 这些步骤也在这里描述:Need BrowserAnimationsModule in Angular but gives error in Universal

因为您还询问了如何解决一般 s-s-r 的“奇怪”问题。我可以给出的一个提示是尝试删除(注释掉)模块和组件,以找出应用程序的哪个部分导致了问题。这就是我在将项目转换为 Universal 时解决大部分问题的方法。

【讨论】:

以上是关于Angular Universal:如何解决缺少的名称、模块和其他奇怪的事情的主要内容,如果未能解决你的问题,请参考以下文章

使用外部 API 调用更新 Angular Universal 中的元标记

如何在 Angular 4 Universal 中发出 http post 请求?

当网站上的文档过时时如何安装 Angular2 Universal?

如何正确启动 Angular Universal 到实时服务器

如何在 Angular Universal 中检测屏幕分辨率?

如何让 Angular Universal 和 PWA 协同工作?