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 到实时服务器