我正在努力将MEAN堆栈应用程序部署到DigitalOcean Droplet。我关注的是tutorial。
该应用程序在我的本地主机上运行正常。
我可以使用tutorial成功配置我的DigitalOcean Droplet。另外,节点服务器使用 PM2 成功启动。但是,当我启动 Angular SSR 命令-npm run start
时,它无法构建应用程序,并出现以下错误-
这是应用程序的基本配置文件。
angular.json
文件-
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"product-bot": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/product-bot/browser",
"index": "src/index.html",
"main": "src/main.browser.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.browser.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"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
}
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/product-bot/server",
"main": "src/main.server.ts",
"tsConfig": "src/tsconfig.server.json"
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "product-bot:build"
},
"configurations": {
"production": {
"browserTarget": "product-bot:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "product-bot: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": [
"src/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/**"
]
}
}
}
},
"product-bot-e2e": {
"root": "e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "product-bot:serve"
},
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "product-bot",
"schematics": {
"@schematics/angular:class": {
"spec": false
},
"@schematics/angular:component": {
"spec": false,
"inlineStyle": true,
"inlineTemplate": true,
"prefix": "app",
"styleext": "scss"
},
"@schematics/angular:directive": {
"spec": false,
"prefix": "app"
},
"@schematics/angular:guard": {
"spec": false
},
"@schematics/angular:module": {
"spec": false
},
"@schematics/angular:pipe": {
"spec": false
},
"@schematics/angular:service": {
"spec": false
}
}
}
package.json
文件-
{
"name": "product-bot",
"version": "0.0.0",
"scripts": {
"start": "npm run build:ssr && npm run serve:ssr",
"sass-lint": "sass-lint -c sass-lint.yml -v -q",
"ts-lint": "ng lint --type-check --force",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors",
"serve:ssr": "node dist/server",
"build:client-and-server-bundles": "ng build --prod && ng run product-bot:server",
"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"lint": "npm run sass-lint && npm run ts-lint",
"release:minor": "standard-version --release-as minor && git push --follow-tags origin master",
"release:major": "standard-version --release-as major && git push --follow-tags origin master",
"ssr:watch": "run-p ssr:universal:build:*",
"ssr:universal:build:browser": "ng run product-bot:build --watch",
"ssr:universal:build:server": "node ./node_modules/npm-delay 12000 && ng run product-bot:server --watch",
"ssr:universal:build:webpack": "node ./node_modules/npm-delay 20000 && webpack --config webpack.server.config.js --watch",
"ssr:universal:build:nodemon": "node ./node_modules/npm-delay 25000 && nodemon --inspect dist/server.js"
},
"private": true,
"dependencies": {
"@angular/animations": "^7.2.14",
"@angular/cdk": "^6.4.7",
"@angular/common": "^7.2.14",
"@angular/compiler": "^7.2.14",
"@angular/core": "^7.2.14",
"@angular/forms": "^7.2.14",
"@angular/http": "^7.2.14",
"@angular/material": "^6.4.7",
"@angular/platform-browser": "^7.2.14",
"@angular/platform-browser-dynamic": "^7.2.14",
"@angular/platform-server": "^7.2.0",
"@angular/router": "^7.2.14",
"@nguniversal/express-engine": "^7.1.0",
"@nguniversal/module-map-ngfactory-loader": "^7.0.2",
"compression": "^1.7.4",
"cookie-parser": "^1.4.4",
"core-js": "^2.5.4",
"cors": "^2.8.5",
"hammerjs": "^2.0.8",
"helmet": "^3.18.0",
"method-override": "^3.0.0",
"mock-browser": "^0.92.14",
"nodemailer": "^5.1.1",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"rxjs": "^6.0.0",
"ts-loader": "^5.3.3",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.6.6",
"@angular/cli": "~7.3.8",
"@angular/compiler-cli": "^7.2.14",
"@angular/language-service": "^7.2.14",
"@auth0/angular-jwt": "^2.1.0",
"@types/jasmine": "~2.8.6",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.9.4",
"axios": "^0.19.0",
"bcryptjs": "^2.4.3",
"codelyzer": "~4.2.1",
"connect-busboy": "0.0.2",
"dotenv": "^6.0.0",
"express": "^4.16.3",
"express-jwt": "^5.3.1",
"express-session": "^1.15.6",
"fs-extra": "^8.1.0",
"gravatar": "^1.8.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"jsonwebtoken": "^8.5.1",
"jwt-decode": "^2.2.0",
"karma": "~1.7.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.0",
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"localstorage-polyfill": "^1.0.1",
"mongoose": "^5.3.1",
"mongoose-express-error-handler": "^1.0.6",
"multer": "^1.4.2",
"ngx-cookie": "^4.1.2",
"ngx-quill-editor": "^2.2.2",
"protractor": "~5.3.0",
"rxjs-compat": "^6.3.3",
"ts-node": "~5.0.1",
"tslint": "~5.9.1",
"typescript": "~3.2.4",
"uniqid": "^5.0.3",
"webpack-cli": "^3.2.1"
},
"browser": {
"http": false,
"https": false,
"net": false,
"path": false,
"stream": false,
"tls": false,
"crypto": false,
"fs": false,
"zlib": false
}
}
server.ts
文件-
import 'zone.js/dist/zone-node';
import { enableProdMode } from '@angular/core';
import * as express from 'express';
import { join } from 'path';
import { ngExpressEngine } from '@nguniversal/express-engine';
import {REQUEST, RESPONSE} from '@nguniversal/express-engine/tokens';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import * as cookieparser from 'cookie-parser';
import * as cors from 'cors';
import * as bodyParser from 'body-parser';
import * as helmet from 'helmet';
import * as compression from 'compression';
import * as methodOverride from 'method-override';
import 'localstorage-polyfill';
import { routes } from './api/routes';
global['localStorage'] = localStorage;
const MockBrowser = require('mock-browser').mocks.MockBrowser;
const mock = new MockBrowser();
global['navigator'] = mock.getNavigator();
const domino = require("domino");
const fs = require("fs");
const path = require("path");
const templateA = fs
.readFileSync(path.join("dist/product-bot/browser", "index.html"))
.toString();
const win = domino.createWindow(templateA);
win.Object = Object;
win.Math = Math;
global["window"] = win;
global["document"] = win.document;
global["branch"] = null;
global["object"] = win.object;
function setDomTypes() {
Object.assign(global, domino['impl']);
(global as any)['KeyboardEvent'] = domino['impl'].Event;
}
setDomTypes();
enableProdMode();
const app = express();
app.use(compression());
app.use(cookieparser());
app.use(helmet());
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(methodOverride());
const PORT = process.env.PORT || 3000;
const DIST_FOLDER = join(process.cwd(), 'dist/product-bot');
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/product-bot/server/main');
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
}));
app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));
app.use('/api', routes);
app.get('*.*', express.static(join(DIST_FOLDER, 'browser'), {
maxAge: '1y'
}));
app.get('*', (req, res) => {
res.render('index', { req });
});
app.listen(PORT, () => {
console.log(`Node server listening on http://localhost:${PORT}`);
});
如果需要在此处添加其他信息,请告诉我。感谢您的帮助。
谢谢!