Angular 通用:readFile$(...).mergeMap 不是函数
Angular Universal: readFile$(...).mergeMap is not a function
我正在对现有 angular 7 应用程序实施 angular 通用服务器端渲染。我也试图让它与 Firebase 一起工作,但是在我的 firebase 控制台功能日志中,我收到以下错误:
TypeError: readFile$(...).mergeMap is not a function
at /user_code/node_modules/angular-universal-express-firebase/node_modules/angular-universal-express/index.js:36:14
at Layer.handle [as handle_request] (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/layer.js:95:5)
at next (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/layer.js:95:5)
at /user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:281:22
at param (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:354:14)
at param (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:365:14)
at Function.process_params (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:410:3)
at next (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:275:10)
我已经设置 firebase.json 将所有路由重定向到一个名为 ssrApp 的函数,并且当我执行 firebase deploy
时不会抛出任何错误。有人遇到过这个问题吗?
这是我的 firebase.json:
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"function": "ssrApp"
}
]
},
"functions": {
"predeploy": "npm --prefix \"$RESOURCE_DIR\" run build"
}
}
这是我在根目录下的package.json:
{
"name": "mse",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"build:client-app:prod": "./node_modules/.bin/ng build --prod",
"build:server-app:prod": "./node_modules/.bin/ng run mse:server",
"build-all": "./node_modules/.bin/npm-run-all build:client-app:prod build:server-app:prod build:functions",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build:functions": "cd functions && npm run build",
"move-index": "mv ./dist/index.html ./functions/lib/index-server.html",
"firebase:serve": "firebase serve --only hosting,functions",
"deploy": "firebase deploy",
"start:local": "npm-run-all build-all move-index firebase:serve",
"build-and-deploy:prod": "npm-run-all build-all move-index deploy"
},
"private": true,
"dependencies": {
"@angular/animations": "^7.2.4",
"@angular/cdk": "^7.3.1",
"@angular/common": "^7.2.4",
"@angular/compiler": "^7.2.4",
"@angular/core": "^7.2.4",
"@angular/forms": "^7.2.4",
"@angular/http": "^7.2.4",
"@angular/material": "^7.3.1",
"@angular/platform-browser": "^7.2.4",
"@angular/platform-browser-dynamic": "^7.2.4",
"@angular/platform-server": "^7.2.4",
"@angular/router": "^7.2.4",
"@nguniversal/module-map-ngfactory-loader": "^7.1.0",
"@ngx-translate/core": "^10.0.2",
"@ngx-translate/http-loader": "^3.0.1",
"@types/googlemaps": "^3.30.16",
"animate.css": "^3.7.0",
"bootstrap": "^4.2.1",
"compass": "^0.1.1",
"compass-sass-mixins": "^0.12.7",
"contentful": "^6.1.3",
"core-js": "^2.6.4",
"emailjs-com": "^2.3.2",
"flag-icon-css": "^3.2.1",
"hammerjs": "^2.0.8",
"jquery": "^3.3.1",
"marked": "^0.4.0",
"ngx-bootstrap": "^3.2.0",
"popper.js": "^1.14.7",
"rxjs": "^6.4.0",
"ts-loader": "^5.3.3",
"web-animations-js": "^2.3.1",
"webpack-cli": "^3.2.3",
"zone.js": "^0.8.29",
"@angular/material-moment-adapter": "7.0.0",
"@nguniversal/express-engine": "^7.0.0",
"express": "^4.16.2",
"moment": "^2.22.2",
"rxjs-compat": "^6.0.0-rc.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.6.8",
"@angular/cli": "~7.3.1",
"@angular/compiler-cli": "^7.2.4",
"@angular/language-service": "^7.2.4",
"@types/jasmine": "^2.8.16",
"@types/jasminewd2": "^2.0.6",
"@types/node": "~8.9.4",
"codelyzer": "~4.2.1",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^1.4.3",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "^5.4.2",
"ts-node": "~5.0.1",
"tslint": "~5.9.1",
"typescript": "~3.2.4",
"@types/express": "^4.0.39",
"http-server": "^0.11.1",
"karma-cli": "~1.0.1",
"npm-run-all": "^4.1.2"
}
}
这是我的 angular.json:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"mse": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles/styles.scss",
"src/styles/mse-theme.scss"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/popper.js/dist/umd/popper.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "mse:build"
},
"configurations": {
"production": {
"browserTarget": "mse:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "mse:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"styles.css"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "functions/lib",
"main": "src/main.server.ts",
"tsConfig": "src/tsconfig.server.json"
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"sourceMap": false,
"optimization": {
"scripts": false,
"styles": true
}
}
}
}
}
},
"mse-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "mse:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "mse"
}
这是我在函数目录中的package.json:
{
"name": "functions",
"scripts": {
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"main": "lib/index.js",
"dependencies": {
"angular-universal-express-firebase": "0.0.4",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.1.0",
"@angular/animations": "^7.2.4",
"@angular/cdk": "^7.3.1",
"@angular/common": "^7.2.4",
"@angular/compiler": "^7.2.4",
"@angular/core": "^7.2.4",
"@angular/forms": "^7.2.4",
"@angular/http": "^7.2.4",
"@angular/material": "^7.3.1",
"@angular/platform-browser": "^7.2.4",
"@angular/platform-browser-dynamic": "^7.2.4",
"@angular/platform-server": "^7.2.4",
"@angular/router": "^7.2.4",
"@nguniversal/module-map-ngfactory-loader": "^7.1.0",
"@ngx-translate/core": "^10.0.2",
"@ngx-translate/http-loader": "^3.0.1",
"@types/googlemaps": "^3.30.16",
"animate.css": "^3.7.0",
"bootstrap": "^4.2.1",
"compass": "^0.1.1",
"compass-sass-mixins": "^0.12.7",
"contentful": "^6.1.3",
"core-js": "^2.6.4",
"emailjs-com": "^2.3.2",
"flag-icon-css": "^3.2.1",
"hammerjs": "^2.0.8",
"jquery": "^3.3.1",
"marked": "^0.4.0",
"ngx-bootstrap": "^3.2.0",
"popper.js": "^1.14.7",
"rxjs": "^6.4.0",
"ts-loader": "^5.3.3",
"web-animations-js": "^2.3.1",
"webpack-cli": "^3.2.3",
"zone.js": "^0.8.29",
"@angular/material-moment-adapter": "7.0.0",
"@nguniversal/express-engine": "^7.0.0",
"express": "^4.16.2",
"moment": "^2.22.2",
"rxjs-compat": "^6.0.0-rc.0"
},
"devDependencies": {
"typescript": "^3.2.2",
"@angular-devkit/build-angular": "^0.6.8",
"@angular/cli": "~7.3.1",
"@angular/compiler-cli": "^7.2.4",
"@angular/language-service": "^7.2.4",
"@types/jasmine": "^2.8.16",
"@types/jasminewd2": "^2.0.6",
"@types/node": "~8.9.4",
"codelyzer": "~4.2.1",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^1.4.3",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "^5.4.2",
"ts-node": "~5.0.1",
"tslint": "~5.9.1",
"@types/express": "^4.0.39",
"http-server": "^0.11.1",
"karma-cli": "~1.0.1",
"npm-run-all": "^4.1.2"
},
"private": true
}
这是我的 index.ts:
import * as angularUniversal from 'angular-universal-express-firebase';
export let ssrApp = angularUniversal.trigger({
index: __dirname + '/index-server.html',
main: __dirname + '/main',
enableProdMode: true,
cdnCacheExpiry: 600,
browserCacheExpiry: 300,
staleWhileRevalidate: 120
});
ng --version:
Angular CLI: 7.3.1
Node: 10.0.0
OS: win32 x64
Angular: 7.2.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
Package Version
------------------------------------------------------------
@angular-devkit/architect 0.6.8
@angular-devkit/build-angular 0.6.8
@angular-devkit/build-optimizer 0.6.8
@angular-devkit/core 0.6.8
@angular-devkit/schematics 7.3.1
@angular/cdk 7.3.1
@angular/cli 7.3.1
@angular/material 7.3.1
@angular/material-moment-adapter 7.0.0
@ngtools/webpack 6.0.8
@schematics/angular 7.3.1
@schematics/update 0.13.1
rxjs 6.4.0
typescript 3.2.4
webpack 4.8.3
更新的答案:
问题似乎是 angular-universal-express-firebase
在 observable 类型上使用了 .mergeMap()
但对于 rxjs
版本 6 或更高版本 .pipe()
必须使用并且 .mergeMap()
必须从 rxjs/operators
.
导入
最好的解决方案是在您的 index.ts 中自己 运行 一个快速应用程序并将其部署到 firebase 云功能(这基本上就是 angular-universal-express-firebase
正在做的)。这使您可以更好地控制服务器上的内容 运行。
这是我的 index.ts:
import * as functions from 'firebase-functions';
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import {renderModuleFactory} from '@angular/platform-server';
import {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader';
import * as express from 'express';
import {readFileSync} from 'fs';
import {enableProdMode} from '@angular/core';
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./main');
enableProdMode();
const app = express();
const indexHtml = readFileSync(__dirname + '/index-server.html', 'utf-8').toString();
app.get('*.*', express.static(__dirname + '/dist', {
maxAge: '1y'
}));
app.route('*').get((req, res) => {
console.log(req.url);
renderModuleFactory(AppServerModuleNgFactory, {
document: indexHtml,
url: req.url,
extraProviders: [
provideModuleMap(LAZY_MODULE_MAP)
]
}).then(html => {
res.status(200).send(html);
}).catch(err => {
console.log(err);
res.sendStatus(500);
});
});
exports.ssrApp = functions.https.onRequest(app);
确保安装顶部导入的所有必需包。同样在您的 firebase.json 中确保所有请求都传递给云函数:
"rewrites": [
{
"source": "**",
"function": "ssrApp"
}
]
初始答案:
问题似乎是 angular-universal-express-firebase
在 observable 类型上使用了 .mergeMap()
但对于 rxjs
版本 6 或更高版本 .pipe()
必须使用并且 .mergeMap()
必须从 rxjs/operators
.
导入
经过几天的研究和尝试不同的方法,这是对我有用的解决方案:
我没有使用 angular-universal-express-firebase
包,而是使用了 angular7-universal-express-firebase
,它基本上更新了代码以适应 .pipe()
方法。
确保卸载 angular-universal-express-firebase
和 angular-universal-express
包以及 运行 项目函数文件夹中的以下命令:
npm install angular7-universal-express-firebase
npm install angular7-universal-express
希望这对 运行 遇到这个问题的其他人有所帮助!
我正在对现有 angular 7 应用程序实施 angular 通用服务器端渲染。我也试图让它与 Firebase 一起工作,但是在我的 firebase 控制台功能日志中,我收到以下错误:
TypeError: readFile$(...).mergeMap is not a function
at /user_code/node_modules/angular-universal-express-firebase/node_modules/angular-universal-express/index.js:36:14
at Layer.handle [as handle_request] (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/layer.js:95:5)
at next (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/layer.js:95:5)
at /user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:281:22
at param (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:354:14)
at param (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:365:14)
at Function.process_params (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:410:3)
at next (/user_code/node_modules/angular-universal-express-firebase/node_modules/express/lib/router/index.js:275:10)
我已经设置 firebase.json 将所有路由重定向到一个名为 ssrApp 的函数,并且当我执行 firebase deploy
时不会抛出任何错误。有人遇到过这个问题吗?
这是我的 firebase.json:
{
"hosting": {
"public": "dist",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"function": "ssrApp"
}
]
},
"functions": {
"predeploy": "npm --prefix \"$RESOURCE_DIR\" run build"
}
}
这是我在根目录下的package.json:
{
"name": "mse",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"build:client-app:prod": "./node_modules/.bin/ng build --prod",
"build:server-app:prod": "./node_modules/.bin/ng run mse:server",
"build-all": "./node_modules/.bin/npm-run-all build:client-app:prod build:server-app:prod build:functions",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build:functions": "cd functions && npm run build",
"move-index": "mv ./dist/index.html ./functions/lib/index-server.html",
"firebase:serve": "firebase serve --only hosting,functions",
"deploy": "firebase deploy",
"start:local": "npm-run-all build-all move-index firebase:serve",
"build-and-deploy:prod": "npm-run-all build-all move-index deploy"
},
"private": true,
"dependencies": {
"@angular/animations": "^7.2.4",
"@angular/cdk": "^7.3.1",
"@angular/common": "^7.2.4",
"@angular/compiler": "^7.2.4",
"@angular/core": "^7.2.4",
"@angular/forms": "^7.2.4",
"@angular/http": "^7.2.4",
"@angular/material": "^7.3.1",
"@angular/platform-browser": "^7.2.4",
"@angular/platform-browser-dynamic": "^7.2.4",
"@angular/platform-server": "^7.2.4",
"@angular/router": "^7.2.4",
"@nguniversal/module-map-ngfactory-loader": "^7.1.0",
"@ngx-translate/core": "^10.0.2",
"@ngx-translate/http-loader": "^3.0.1",
"@types/googlemaps": "^3.30.16",
"animate.css": "^3.7.0",
"bootstrap": "^4.2.1",
"compass": "^0.1.1",
"compass-sass-mixins": "^0.12.7",
"contentful": "^6.1.3",
"core-js": "^2.6.4",
"emailjs-com": "^2.3.2",
"flag-icon-css": "^3.2.1",
"hammerjs": "^2.0.8",
"jquery": "^3.3.1",
"marked": "^0.4.0",
"ngx-bootstrap": "^3.2.0",
"popper.js": "^1.14.7",
"rxjs": "^6.4.0",
"ts-loader": "^5.3.3",
"web-animations-js": "^2.3.1",
"webpack-cli": "^3.2.3",
"zone.js": "^0.8.29",
"@angular/material-moment-adapter": "7.0.0",
"@nguniversal/express-engine": "^7.0.0",
"express": "^4.16.2",
"moment": "^2.22.2",
"rxjs-compat": "^6.0.0-rc.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.6.8",
"@angular/cli": "~7.3.1",
"@angular/compiler-cli": "^7.2.4",
"@angular/language-service": "^7.2.4",
"@types/jasmine": "^2.8.16",
"@types/jasminewd2": "^2.0.6",
"@types/node": "~8.9.4",
"codelyzer": "~4.2.1",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^1.4.3",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "^5.4.2",
"ts-node": "~5.0.1",
"tslint": "~5.9.1",
"typescript": "~3.2.4",
"@types/express": "^4.0.39",
"http-server": "^0.11.1",
"karma-cli": "~1.0.1",
"npm-run-all": "^4.1.2"
}
}
这是我的 angular.json:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"mse": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
}
},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles/styles.scss",
"src/styles/mse-theme.scss"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/popper.js/dist/umd/popper.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "mse:build"
},
"configurations": {
"production": {
"browserTarget": "mse:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "mse:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"styles.css"
],
"scripts": [],
"assets": [
"src/favicon.ico",
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "functions/lib",
"main": "src/main.server.ts",
"tsConfig": "src/tsconfig.server.json"
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"sourceMap": false,
"optimization": {
"scripts": false,
"styles": true
}
}
}
}
}
},
"mse-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "mse:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "mse"
}
这是我在函数目录中的package.json:
{
"name": "functions",
"scripts": {
"build": "tsc",
"serve": "npm run build && firebase serve --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"main": "lib/index.js",
"dependencies": {
"angular-universal-express-firebase": "0.0.4",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.1.0",
"@angular/animations": "^7.2.4",
"@angular/cdk": "^7.3.1",
"@angular/common": "^7.2.4",
"@angular/compiler": "^7.2.4",
"@angular/core": "^7.2.4",
"@angular/forms": "^7.2.4",
"@angular/http": "^7.2.4",
"@angular/material": "^7.3.1",
"@angular/platform-browser": "^7.2.4",
"@angular/platform-browser-dynamic": "^7.2.4",
"@angular/platform-server": "^7.2.4",
"@angular/router": "^7.2.4",
"@nguniversal/module-map-ngfactory-loader": "^7.1.0",
"@ngx-translate/core": "^10.0.2",
"@ngx-translate/http-loader": "^3.0.1",
"@types/googlemaps": "^3.30.16",
"animate.css": "^3.7.0",
"bootstrap": "^4.2.1",
"compass": "^0.1.1",
"compass-sass-mixins": "^0.12.7",
"contentful": "^6.1.3",
"core-js": "^2.6.4",
"emailjs-com": "^2.3.2",
"flag-icon-css": "^3.2.1",
"hammerjs": "^2.0.8",
"jquery": "^3.3.1",
"marked": "^0.4.0",
"ngx-bootstrap": "^3.2.0",
"popper.js": "^1.14.7",
"rxjs": "^6.4.0",
"ts-loader": "^5.3.3",
"web-animations-js": "^2.3.1",
"webpack-cli": "^3.2.3",
"zone.js": "^0.8.29",
"@angular/material-moment-adapter": "7.0.0",
"@nguniversal/express-engine": "^7.0.0",
"express": "^4.16.2",
"moment": "^2.22.2",
"rxjs-compat": "^6.0.0-rc.0"
},
"devDependencies": {
"typescript": "^3.2.2",
"@angular-devkit/build-angular": "^0.6.8",
"@angular/cli": "~7.3.1",
"@angular/compiler-cli": "^7.2.4",
"@angular/language-service": "^7.2.4",
"@types/jasmine": "^2.8.16",
"@types/jasminewd2": "^2.0.6",
"@types/node": "~8.9.4",
"codelyzer": "~4.2.1",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^1.4.3",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "^5.4.2",
"ts-node": "~5.0.1",
"tslint": "~5.9.1",
"@types/express": "^4.0.39",
"http-server": "^0.11.1",
"karma-cli": "~1.0.1",
"npm-run-all": "^4.1.2"
},
"private": true
}
这是我的 index.ts:
import * as angularUniversal from 'angular-universal-express-firebase';
export let ssrApp = angularUniversal.trigger({
index: __dirname + '/index-server.html',
main: __dirname + '/main',
enableProdMode: true,
cdnCacheExpiry: 600,
browserCacheExpiry: 300,
staleWhileRevalidate: 120
});
ng --version:
Angular CLI: 7.3.1
Node: 10.0.0
OS: win32 x64
Angular: 7.2.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
Package Version
------------------------------------------------------------
@angular-devkit/architect 0.6.8
@angular-devkit/build-angular 0.6.8
@angular-devkit/build-optimizer 0.6.8
@angular-devkit/core 0.6.8
@angular-devkit/schematics 7.3.1
@angular/cdk 7.3.1
@angular/cli 7.3.1
@angular/material 7.3.1
@angular/material-moment-adapter 7.0.0
@ngtools/webpack 6.0.8
@schematics/angular 7.3.1
@schematics/update 0.13.1
rxjs 6.4.0
typescript 3.2.4
webpack 4.8.3
更新的答案:
问题似乎是 angular-universal-express-firebase
在 observable 类型上使用了 .mergeMap()
但对于 rxjs
版本 6 或更高版本 .pipe()
必须使用并且 .mergeMap()
必须从 rxjs/operators
.
最好的解决方案是在您的 index.ts 中自己 运行 一个快速应用程序并将其部署到 firebase 云功能(这基本上就是 angular-universal-express-firebase
正在做的)。这使您可以更好地控制服务器上的内容 运行。
这是我的 index.ts:
import * as functions from 'firebase-functions';
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import {renderModuleFactory} from '@angular/platform-server';
import {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader';
import * as express from 'express';
import {readFileSync} from 'fs';
import {enableProdMode} from '@angular/core';
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./main');
enableProdMode();
const app = express();
const indexHtml = readFileSync(__dirname + '/index-server.html', 'utf-8').toString();
app.get('*.*', express.static(__dirname + '/dist', {
maxAge: '1y'
}));
app.route('*').get((req, res) => {
console.log(req.url);
renderModuleFactory(AppServerModuleNgFactory, {
document: indexHtml,
url: req.url,
extraProviders: [
provideModuleMap(LAZY_MODULE_MAP)
]
}).then(html => {
res.status(200).send(html);
}).catch(err => {
console.log(err);
res.sendStatus(500);
});
});
exports.ssrApp = functions.https.onRequest(app);
确保安装顶部导入的所有必需包。同样在您的 firebase.json 中确保所有请求都传递给云函数:
"rewrites": [
{
"source": "**",
"function": "ssrApp"
}
]
初始答案:
问题似乎是 angular-universal-express-firebase
在 observable 类型上使用了 .mergeMap()
但对于 rxjs
版本 6 或更高版本 .pipe()
必须使用并且 .mergeMap()
必须从 rxjs/operators
.
经过几天的研究和尝试不同的方法,这是对我有用的解决方案:
我没有使用 angular-universal-express-firebase
包,而是使用了 angular7-universal-express-firebase
,它基本上更新了代码以适应 .pipe()
方法。
确保卸载 angular-universal-express-firebase
和 angular-universal-express
包以及 运行 项目函数文件夹中的以下命令:
npm install angular7-universal-express-firebase
npm install angular7-universal-express
希望这对 运行 遇到这个问题的其他人有所帮助!