Angular Universal : How to resolve missing names, modules and other weird things

若如初见. 提交于 2019-12-11 04:08:43

问题


Everything works well in the main app, but trying to serve the bundled SSR produces errors I don't understand. I'll post everything below regarding setup.

There are too many small pieces that just break, everywhere, I hope the process of producing a server side app will improve with time.

Also there are parts of this setup I'm not really confident about as I'm still trying to get the hang of this, any suggestions for improvement will be appreciated, thanks.

functions : package 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
}

The server functions

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);

Server TS Config

{
    "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"
    ]
}

I serve with firebase serve --only functions, after serving I get different kind of errors, after fixing, another one will come up.

So far I'm stuck on this.

TypeError: Cannot read property 'name' of undefined

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)

THE ORIGIN 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';

回答1:


Solutions:

  1. use npm run build --prod --aot
  2. There may be a name variable in your component but you are not initialized any value to it ( eg: public name: any = "title";)



回答2:


My guess is the "undefined error" you are getting is caused, because on the server you can't use the browser objects (window, document, navigator).
See: https://github.com/angular/universal
You could try the following:

  • In your AppModule you are including the BrowserAnimationsModule. Remove this Module.
  • In the ServerModule include the NoopAnimationsModule. (So you don't get errors because your animations are missing)
  • Create a new BrowserModule which includes the BrowserAnimationsModule and the AppModule. The BrowserModule should also bootstrap the AppComponent.
  • In your main.ts bootstrap the new BrowserModule.

I hope this helps you resolve your issue.
These steps are also described here: Need BrowserAnimationsModule in Angular but gives error in Universal

Since you also asked how to resolve "weird" issues with SSR in general. One tip I can give is to try and remove(comment out) modules and components to find out which part of the application is causing an issue. Thats how I resolved most of the issues, while I was converting a project to Universal.



来源:https://stackoverflow.com/questions/49472738/angular-universal-how-to-resolve-missing-names-modules-and-other-weird-things

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!