Node.js / Express with vhost 与 Sails.js 框架应用程序冲突

Posted

技术标签:

【中文标题】Node.js / Express with vhost 与 Sails.js 框架应用程序冲突【英文标题】:Node.js / Express with vhost conflict with Sails.js framework app 【发布时间】:2014-10-10 07:27:45 【问题描述】:

我正在尝试将我的 Nodejs/Express 托管服务器设置为在我的 VPS 上运行多个应用程序(Sails.js 应用程序类型),但出现此错误:

/srv/data/web/vhosts/default/node_modules/vhost/index.js:78
  throw new TypeError('argument server is unsupported')
        ^
TypeError: argument server is unsupported
   at createHandle (/srv/data/web/vhosts/default/node_modules/vhost/index.js:78:9)
   at vhost (/srv/data/web/vhosts/default/node_modules/vhost/index.js:39:16)
   at Object.<anonymous> (/srv/data/web/vhosts/default/server.js:46:9)
   at Module._compile (module.js:456:26)
   at Object.Module._extensions..js (module.js:474:10)
   at Module.load (module.js:356:32)
   at Function.Module._load (module.js:312:12)
   at Function.Module.runMain (module.js:497:10)
   at startup (node.js:119:16)
   at node.js:906:3

当然,我之前安装了所有依赖项。 我的多个应用程序的 Nodejs/Express 基本配置很好,因为它适用于这个 express vhosts 示例配置:https://github.com/loicsaintroch/express-vhosts

所以这里是我的 nodejs 服务器应用程序结构:

.../vhosts/default/server.js
                   package.json
                  /app1
                       /app.js
                  /app2
                       /app.js
                  /app3
                       /app.js

这里是我的 server.js 文件,基于之前的 github 示例:

// Module dependencies
var express = require('express');
var vhost = require('vhost');
var app = express();

// vhosts
app
  .use(vhost('app1.com', require('./app1/app.js')))
  .listen(8080);

还有 package.json 文件:


  "name": "default",
  "private": true,
  "version": "0.0.1",
  "description": "Default git repository for some web applications.",
  "dependencies": 
    "express": "^4.2.0",
    "vhost": "^2.0.0",
    "forever": "^0.11.1",
    "static-favicon": "^1.0.0",
    "ejs": "^1.0.0",
    "morgan": "^1.0.0",
    "cookie-parser": "^1.0.1",
    "body-parser": "^1.0.0",
    "debug": "^0.7.4"
  ,
  "scripts": 
    "start": "forever start server.js --prod",
    "debug": "node debug server.js"
  ,
  "main": "server.js"

错误来自 vhost npm 包

/**
 * Create handle to server.
 *
 * @param function|Server server
 * @return function
 * @api private
 */

function createHandle(server)
  if (typeof server === 'function') 
    // callable servers are the handle
    return server
   else if (typeof server.emit === 'function') 
    // emit request event on server
    return function handle(req, res) 
      server.emit('request', req, res)
    
  

  throw new TypeError('argument server is unsupported')

好的,我认为 vhost 包sails.js 框架app.js 响应有问题。这是来自我的 Sails.js 应用程序的 app.js 文件内容:

/**
 * app.js
 *
 * Use `app.js` to run your app without `sails lift`.
 * To start the server, run: `node app.js`.
 *
 * This is handy in situations where the sails CLI is not relevant or useful.
 *
 * For example:
 *   => `node app.js`
 *   => `forever start app.js`
 *   => `node debug app.js`
 *   => `modulus deploy`
 *   => `heroku scale`
 *
 *
 * The same command-line arguments are supported, e.g.:
 * `node app.js --silent --port=80 --prod`
 */

// Ensure a "sails" can be located:
(function() 
  var sails;
  try 
    sails = require('sails');
   catch (e) 
    console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.');
    console.error('To do that, run `npm install sails`');
    console.error('');
    console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.');
    console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,');
    console.error('but if it doesn\'t, the app will run with the global sails instead!');
    return;
  

  // Try to get `rc` dependency
  var rc;
  try 
    rc = require('rc');
   catch (e0) 
    try 
      rc = require('sails/node_modules/rc');
     catch (e1) 
      console.error('Could not find dependency: `rc`.');
      console.error('Your `.sailsrc` file(s) will be ignored.');
      console.error('To resolve this, run:');
      console.error('npm install rc --save');
      rc = function ()  return ; ;
    
  


  // Start server
  sails.lift(rc('sails'));
)();

===============================================

更新:完整解决方案示例 作为出色答案的综合,我在这里写了一个完整的案例研究 https://github.com/migswd/express-sails-vhosts

===============================================

【问题讨论】:

【参考方案1】:

这里的问题是,您试图硬塞一个旨在让 Express 应用与 Sails 应用配合使用的示例。

如果您查看示例 vhost 应用程序中的 app.js 文件,它们都使用 module.exports 返回 Express 应用程序实例。您发布的 Sails 应用中的 app.js 显然没有这样做;它根本不导出任何东西。此外,该文件正在调用sails.lift,它会启动自己的服务器,侦听端口 1337。

一点点肘部油脂就可以让它发挥作用。您可以使用sails.load 而不是启动 Sails 应用程序,它会执行所有操作除了开始侦听端口。这是一种异步方法,因此还需要对 server.js 进行改造。

Sails app.js 文件变为:

var sails = require('sails');
module.exports = function(cb) 
    process.chdir(__dirname);
    sails.load(cb);
;

每个正在运行的 sails 实例都将其底层 Express 应用程序公开为 .hooks.http.app,因此在您的 server.js 中,使用 async 或类似的东西来加载所有 Sails 应用程序,然后挂钩他们与vhost

// Module dependencies
var express = require('express');
var vhost = require('vhost');
var app = express();
var async = require('async');

async.auto(

    app1: require('./app1/app.js'),
    app2: require('./app2/app.js'),
    app3: require('./app3/app.js')

, function doneLoadingApps(err, apps) 

    app
      .use(vhost('app1.io', apps.app1.hooks.http.app))
      .use(vhost('app2.io', apps.app2.hooks.http.app))
      .use(vhost('app3.io', apps.app3.hooks.http.app))
      // Mix in a vanilla Express app as well
      .use(vhost('app4.io', require('./app4/app.js')))
      .listen(8080);

);

【讨论】:

OK 测试您的提案,但出现错误:/srv/data/web/vhosts/default/server.js:10 app ^ ReferenceError: app is not defined at doneLoadingApps (/srv/data/web/ vhosts/default/server.js:10:5) 在 /srv/data/web/vhosts/default/node_modules/async/lib/async.js:454:17 在 /srv/data/web/vhosts/default/node_modules /async/lib/async.js:444:17 at Array.forEach (native) at _each .. 对不起,是的,您仍然需要制作一个真正的快递应用程序。我只是展示了添加的部分。调整我的答案以匹配。 非常适合 Sails!只是为了验证您的答案和主题的完整解决方案,我想让 server.js 配置启动风帆和非风帆(快速)虚拟主机。我将 app1 链接到原始示例中的 app1,但出现此错误:/srv/data/web/vhosts/default/node_modules/express/lib/router/index.js:120 var search = 1 + req.url.indexOf( '?'); ^ TypeError:无法在 Function.proto.handle (/srv/data/web/vhosts/default/node_modules/express/lib/router/index.js:120:28) 调用未定义的方法 'indexOf' 让我在这里做所有的工作,嗯?您可能正在尝试将 vanilla Express 应用程序包含在 async.auto 块中,但这不起作用,因为它的 app.js 不会像 Sails 应用程序那样返回异步函数。只需像在原始示例中一样添加它即可。更新了我的示例以进行演示。 你是老板! :D 我正在考虑类似的事情,但无法弄清楚。不是我懒惰,而是我是 nodejs 婴儿潮一代 :D 非常感谢! CU...

以上是关于Node.js / Express with vhost 与 Sails.js 框架应用程序冲突的主要内容,如果未能解决你的问题,请参考以下文章

我无法将数据存储到 Postman 上的 MongoDB(Atlas)中(Node.js with express)

尝试将 Node.js (Express) 设置为与虚拟主机一起使用,并遇到意外错误

node.js express配置允许跨域

node开发node.js编写一个接口

LetsEncrypted Node.js HTTPS Express无法从浏览器访问

前端node.js框架node.js框架express