如何在现有的node项目中添加Angular Universal生成的express应用程序

2024-01-01

我的情况如下:我有一个带有express的节点服务器,它一方面为我提供几个角度应用程序,另一方面响应来自api的请求。它们中的每一个都配置了一个路由,最后所有的东西都从一个端口监听。

现在我正在使用 Angular Universal 准备一个新的角度应用程序。按照官方 Angular 指南的步骤,使用 Express、Genre 和 server.ts 文件实现 Universal。该文件将负责渲染内容并引发服务器在端口中的侦听。

这就是我的问题的来源。我的意图是该服务器不监听任何端口,相反,我想导出 app 变量并将其导入到我现有的节点项目中,这样我就可以让多个应用程序在单个端口中监听。我知道我可以将节点服务器的内容添加到 server.ts 文件中,但出于几个重要原因,我希望将其分开。

我尝试将变量 app 导出到文件 server.ts 中,使用 webpack 类型化 server.js,在现有节点服务器中导入变量并添加 app.use (universalapp) 来添加它。我已经尝试了很多方法,但我没有得到它,在大多数情况下导入 server.js 返回 undefined 或 {}。我希望能够很好地解释自己,如果您需要更多数据,请随时告诉我。非常感谢您的帮助,我等待您的答复。

为了更好地理解,这里是我的代码:

我现有的节点服务器(app.js):

'use strict'

// Imports y variables
var express        = require("express"),
    bodyParser     = require("body-parser"),
    cors           = require("cors"),
    morgan         = require("morgan"),
    methodOverride = require("method-override"),
    https          = require("https"),              // --> PARA PRODUCCIÓN
    // http          = require("http"),             // --> PARA LOCAL
    helmet         = require("helmet"),
    path           = require("path"),
    compression    = require("compression"),
    fs             = require('fs'),
    appConfig      = require('./config/global').config.app,
    app            = express();


var option = {
    key: fs.readFileSync(appConfig.certOptions.sslPath + appConfig.certOptions.key),
    cert: fs.readFileSync(appConfig.certOptions.sslPath + appConfig.certOptions.cert),
    ca: fs.readFileSync(appConfig.certOptions.sslPath + appConfig.certOptions.ca)
};                                                 // --> PARA PRODUCCIÓN

var server = https.createServer(option, app);       // --> PARA PRODUCCIÓN
//  var server = http.createServer(app);             // --> PARA LOCAL

// Middlewares
app.use(bodyParser.urlencoded({
    limit: appConfig.limit,
    parameterLimit: appConfig.parameterLimit,
    extended: false
}));
app.use(bodyParser.json({
    limit: appConfig.limit
}));
app.use(methodOverride());
app.use(morgan(appConfig.logMode));                          // Genera logs
app.use(helmet());                                          // Seguridad
app.use(cors());                                            // Habilita las cabeceras y accesos
app.use(compression());    

// Para servir la aplicación angular
app.use(express.static(path.join(__dirname, 'dist')));                          // Panel web
app.use('/clientes', express.static(path.join(__dirname, 'clientes/dist/coplanapwa')));    // App web

// Cualquier otra ruta devulve la aplicación angular
var web = require('./routes/web');

// API - Rutas
var user_routes          = require('./routes/user'),
    map_routes           = require('./routes/map'),
    doc_routes           = require('./routes/doc'),
    plaga_routes         = require('./routes/plaga'),
    recomendacion_routes = require('./routes/recomendacion'),
    valoracion_routes    = require('./routes/valoracion'),
    app_routes           = require('./routes/app');

// API - Middlewares
app.use('/api', user_routes);
app.use('/api', map_routes);
app.use('/api', doc_routes);
app.use('/api', plaga_routes);
app.use('/api', recomendacion_routes);
app.use('/api', valoracion_routes);
app.use('/api', app_routes);

app.use(web);

module.exports = server;

我现有的节点服务器(index.js):

'use strict'

var mongoose = require('mongoose');
var server = require('./app');
var db = require('./config/global').config.db;
var port = require('./config/global').config.app.port;


// Conexión e inicio server
mongoose.Promise = global.Promise;
mongoose.connect(process.env.MONGODB_URI || 'mongodb://'+db.user+':'+db.password+'@'+db.host+':'+db.port+'/'+db.scheme, function(err, res) { 
    if(err) {
      console.log('ERROR: No ha sido posible conectar a la base de datos. ' + err);
    }
    server.listen(port, function() {
      console.log("El servidor local con Node y Express está corriendo correctamente en https://xyz.ab:" + port);
    });    
});

我的 TypeScript 中的 Angular 通用节点应用程序 (server.ts)

'use strict'
// These are important and needed before anything else
import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import { enableProdMode } from '@angular/core';

import * as express from 'express';
import { join } from 'path';


// FIX para los accesores al dom y propiedades exclusivas del navegador
const MockBrowser = require('mock-browser').mocks.MockBrowser;
const mock = new MockBrowser();
global['document'] = mock.getDocument();
global['window'] = mock.getWindow();
global['location'] = mock.getLocation();
global['navigator'] = mock.getNavigator();
global['history'] = mock.getHistory();
global['localStorage'] = mock.getLocalStorage();
global['sessionStorage'] = mock.getSessionStorage();

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const DIST_FOLDER = join(process.cwd(), 'clientes/dist');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./clientes/dist/coplanapwa-server/main');

// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'coplanapwa'));

// Server static files from /coplanapwa
app.get('*.*', express.static(join(DIST_FOLDER, 'coplanapwa')));

// All regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', { req });
});

// Start up the Node server

// const PORT = process.env.UNIVERSAL_PORT || 8002;
// app.listen(PORT, () => {
//     console.log(`El servidor local con Node y Express está corriendo correctamente en https://xyz.ab:${PORT}`);
//   });

export default app;

使用 webpack (server.js) 生成的 server.js 文件的片段:

    /******/ (function(modules) { // webpackBootstrap
    /******/    // The module cache
    /******/    var installedModules = {};
    /******/
    /******/    // The require function
    /******/    function __webpack_require__(moduleId) {
    /******/
    /******/        // Check if module is in cache
    /******/        if(installedModules[moduleId]) {
    /******/            return installedModules[moduleId].exports;
    /******/        }
    /******/        // Create a new module (and put it into the cache)
    /******/        var module = installedModules[moduleId] = {
    /******/            i: moduleId,
    /******/            l: false,
    /******/            exports: {}
    /******/        };
    /******/
    /******/        // Execute the module function
    /******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    /******/
    /******/        // Flag the module as loaded
    /******/        module.l = true;
    /******/
    /******/        // Return the exports of the module
    /******/        return module.exports;
    /******/    }
    /******/
    /******/
    /******/    // expose the modules object (__webpack_modules__)
    /******/    __webpack_require__.m = modules;
    /******/
    /******/    // expose the module cache
    /******/    __webpack_require__.c = installedModules;
    /******/
    /******/    // define getter function for harmony exports
    /******/    __webpack_require__.d = function(exports, name, getter) {
    /******/        if(!__webpack_require__.o(exports, name)) {
    /******/            Object.defineProperty(exports, name, { enumerable: true, get: getter });
    /******/        }
    /******/    };
    /******/
    /******/    // define __esModule on exports
    /******/    __webpack_require__.r = function(exports) {
    /******/        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
    /******/            Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
    /******/        }
    /******/        Object.defineProperty(exports, '__esModule', { value: true });
    /******/    };
    /******/
    /******/    // create a fake namespace object
    /******/    // mode & 1: value is a module id, require it
    /******/    // mode & 2: merge all properties of value into the ns
    /******/    // mode & 4: return value when already ns object
    /******/    // mode & 8|1: behave like require
    /******/    __webpack_require__.t = function(value, mode) {
    /******/        if(mode & 1) value = __webpack_require__(value);
    /******/        if(mode & 8) return value;
    /******/        if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
    /******/        var ns = Object.create(null);
    /******/        __webpack_require__.r(ns);
    /******/        Object.defineProperty(ns, 'default', { enumerable: true, value: value });
    /******/        if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
    /******/        return ns;
    /******/    };
    /******/
    /******/    // getDefaultExport function for compatibility with non-harmony modules
    /******/    __webpack_require__.n = function(module) {
    /******/        var getter = module && module.__esModule ?
    /******/            function getDefault() { return module['default']; } :
    /******/            function getModuleExports() { return module; };
    /******/        __webpack_require__.d(getter, 'a', getter);
    /******/        return getter;
    /******/    };
    /******/
    /******/    // Object.prototype.hasOwnProperty.call
    /******/    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
    /******/
    /******/    // __webpack_public_path__
    /******/    __webpack_require__.p = "";
    /******/
    /******/
    /******/    // Load entry module and return exports
    /******/    return __webpack_require__(__webpack_require__.s = 0);
    /******/ })
    /************************************************************************/
    /******/ ([
    /* 0 */
    /***/ (function(module, __webpack_exports__, __webpack_require__) {

    "use strict";
    __webpack_require__.r(__webpack_exports__);
    /* harmony import */ var zone_js_dist_zone_node__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
    /* harmony import */ var zone_js_dist_zone_node__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(zone_js_dist_zone_node__WEBPACK_IMPORTED_MODULE_0__);
    /* harmony import */ var reflect_metadata__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
    /* harmony import */ var reflect_metadata__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(reflect_metadata__WEBPACK_IMPORTED_MODULE_1__);
    /* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
    /* harmony import */ var express__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(208);
    /* harmony import */ var express__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(express__WEBPACK_IMPORTED_MODULE_3__);
    /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(215);
    /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_4__);
    /* harmony import */ var _nguniversal_express_engine__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1069);
    /* harmony import */ var _nguniversal_module_map_ngfactory_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1071);

    // These are important and needed before anything else






    // FIX para los accesores al dom y propiedades exclusivas del navegador
    var MockBrowser = __webpack_require__(333).mocks.MockBrowser;
    var mock = new MockBrowser();
    global['document'] = mock.getDocument();
    global['window'] = mock.getWindow();
    global['location'] = mock.getLocation();
    global['navigator'] = mock.getNavigator();
    global['history'] = mock.getHistory();
    global['localStorage'] = mock.getLocalStorage();
    global['sessionStorage'] = mock.getSessionStorage();
    // Faster server renders w/ Prod mode (dev mode never needed)
    Object(_angular_core__WEBPACK_IMPORTED_MODULE_2__["enableProdMode"])();
    // Express server
    var app = express__WEBPACK_IMPORTED_MODULE_3__();
    // let app: any = express();
    var DIST_FOLDER = Object(path__WEBPACK_IMPORTED_MODULE_4__["join"])(process.cwd(), 'clientes/dist');
    // * NOTE :: leave this as require() since this file is built Dynamically from webpack
    var _a = __webpack_require__(917), AppServerModuleNgFactory = _a.AppServerModuleNgFactory, LAZY_MODULE_MAP = _a.LAZY_MODULE_MAP;
    // Express Engine

    // Import module map for lazy loading

    app.engine('html', Object(_nguniversal_express_engine__WEBPACK_IMPORTED_MODULE_5__["ngExpressEngine"])({
        bootstrap: AppServerModuleNgFactory,
        providers: [
            Object(_nguniversal_module_map_ngfactory_loader__WEBPACK_IMPORTED_MODULE_6__["provideModuleMap"])(LAZY_MODULE_MAP)
        ]
    }));
    app.set('view engine', 'html');
    app.set('views', Object(path__WEBPACK_IMPORTED_MODULE_4__["join"])(DIST_FOLDER, 'coplanapwa'));
    // Server static files from /coplanapwa
    app.get('clientes/*.*', express__WEBPACK_IMPORTED_MODULE_3__["static"](Object(path__WEBPACK_IMPORTED_MODULE_4__["join"])(DIST_FOLDER, 'coplanapwa')));
    // All regular routes use the Universal engine
    app.get('clientes/*', function (req, res) {
        res.render('index', { req: req });
    });
...And about 28,000 more lines

Package.json 构建脚本:

"build:prod": "ng build --configuration production --build-optimizer --vendor-chunk --base-href /clientes/ --deploy-url /clientes/",
"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:ssr": "node clientes/dist/server",
"build:client-and-server-bundles": "npm run build:prod && ng run coplanapwa:server",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors",

我想做的是做这样的事情:

服务器.ts:

// Express server
const app = express();
// More code ...
export default app;

app.js:

var express = require("express");
var app = express();
var universalapp = require("./universalapp/server.js");
app.use('/clientes', universalapp);
// More code ...

更新2018/10/17

我曾尝试使用相同的代码但在 javascript 中创建 server.js 而不是 server.ts,但是当我无法识别 ECMAScript2015 的导入时,它会给我错误。我把我所做的端口和错误放在一起,以便更好地理解。为了让您更好地理解,我向您展示代码:

服务器.js

'use strict'
// These are important and needed before anything else
require('zone.js/dist/zone-node');
require('reflect-metadata');

const { enableProdMode } = require('@angular/core');
const express = require('express');

const { join } = require('path');

// FIX para los accesores al dom y propiedades exclusivas del navegador
const MockBrowser = require('mock-browser').mocks.MockBrowser;
const mock = new MockBrowser();
global['document'] = mock.getDocument();
global['window'] = mock.getWindow();
global['location'] = mock.getLocation();
global['navigator'] = mock.getNavigator();
global['history'] = mock.getHistory();
global['localStorage'] = mock.getLocalStorage();
global['sessionStorage'] = mock.getSessionStorage();

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const DIST_FOLDER = join(process.cwd(), 'clientes/dist');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('clientes/dist/coplanapwa-server/main');

// Express Engine
const { ngExpressEngine } = require('@nguniversal/express-engine');
// Import module map for lazy loading
const { provideModuleMap } = require('@nguniversal/module-map-ngfactory-loader');

app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'coplanapwa'));

// Server static files from /coplanapwa
app.get('*.*', express.static(join(DIST_FOLDER, 'coplanapwa')));

// All regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', { req });
});

// Start up the Node server

const PORT = process.env.UNIVERSAL_PORT || 8002;
app.listen(PORT, () => {
    console.log(`El servidor local con Node y Express está corriendo correctamente en https://xys.ab:${PORT}`);
  });

// export default app;
// export const APP = app;

节点输出错误:

import { Injectable, Inject } from '@angular/core';
^^^^^^

SyntaxError: Unexpected token import

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在现有的node项目中添加Angular Universal生成的express应用程序 的相关文章

随机推荐