我正在努力将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","tsConfig": "src/tsconfig.spec.json","karmaConfig": "src/karma.conf.js","scripts": [],"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/","architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor","options": {
"protractorConfig": "e2e/protractor.conf.js","devserverTarget": "product-bot:serve"
},},"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,"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}`);
});
如果需要在此处添加其他信息,请告诉我。感谢您的帮助。
谢谢!