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

时间:2018-03-25 05:10:33

标签: angular typescript firebase google-cloud-functions serverside-rendering

在主应用程序中一切运行良好,但尝试服务捆绑的SSR会产生我不明白的错误。我将发布以下有关设置的所有内容。

在世界各地都有太多的小碎片,我希望生产服务器端应用程序的过程会随着时间的推移而改善。

此设置的某些部分我并不十分自信,因为我仍然试图掌握这一点,任何改进建议都将不胜感激,谢谢。

功能:包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 ssrapp = 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:无法读取属性' name'未定义的

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)

原创APP:

PACKAGE 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';

2 个答案:

答案 0 :(得分:1)

解决方案:

  1. 使用npm run build --prod --aot
  2. 您的组件中可能有一个名称变量,但您没有初始化任何值(例如:公共名称:任何="标题&#34 ;;)

答案 1 :(得分:1)

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

  • 在AppModule中,您将包含BrowserAnimationsModule。删除此模块。
  • 在ServerModule中包含NoopAnimationsModule。 (所以你不要 由于缺少动画而导致错误)
  • 创建一个包含BrowserAnimationsModule的新BrowserModule 和AppModule。 BrowserModule也应该引导 AppComponent。
  • 在你的main.ts引导新的BrowserModule。

我希望这可以帮助您解决问题 这里还介绍了这些步骤:Need BrowserAnimationsModule in Angular but gives error in Universal

因为你也问过如何解决"怪异的" SSR的问题一般。我可以给出的一个提示是尝试删除(注释掉)模块和组件,以找出应用程序的哪个部分导致问题。这就是我在解决大多数问题的过程中,当时我正在将项目转换为Universal。