1

我正在开发基于 node.js 的框架/服务器。该框架启动一个快速服务器并自动从本地目录加载所有插件。框架和各个插件都有自己的 git 存储库。

框架在这里:https ://github.com/Appsecute/appsecute-connector-multi (参见 server.js 插件加载)。

一个示例插件在这里:https ://github.com/Appsecute/appsecute-connector-multi-heroku ://github.com/Appsecute/appsecute-connector-multi-heroku (有关插件定义/引导文件,请参见 connector.js)。

这一切都在本地正常工作。现在是时候将它部署到 Heroku。我的计划是编写一个小脚本,克隆框架 + 指定插件并构建一个可以部署的文件夹结构。

我在这里写了这个脚本:https ://github.com/Appsecute/appsecute-connector-multi-deployment

现在,关于我的问题,是否可以指示 Heroku 在应用程序的根目录(框架)以及特定的子目录(每个插件)中执行“npm install”?

我知道节点会查看相对于正在加载模块的脚本最近的 node_modules 文件夹,因此如果插件尝试加载模块,那么节点将首先查看 app_root/plugins/plugin_name/node_modules - 这正是我想要的,我只需要 Heroku 来确保模块在那里。

我最初计划让我的构建脚本转到各个目录并运行 npm 安装,但后来我记得 Heroku 将执行自己的 npm 安装。

我的另一个选择是编写一些代码来检查每个插件 package.json 文件中的所有依赖项,然后对所有依赖项进行联合并将它们写到 package.json 到应用程序的根目录中。这样,当 Heroku 执行 npm install 时,所有依赖项都将被安装。这听起来很脆弱,并且当不同的插件指定同一模块的不同版本时可能会失败。

而这一切最终引出了一个问题,我只是做错了吗?我应该查看不同的架构/回购结构等吗?

4

1 回答 1

2

在花了一段时间追求脚本选项之后,我意识到我应该利用 Node 模块系统和 NPM 来为我处理所有这些。

我最终删除了脚本,而不是框架从插件目录加载插件,它现在期望在实例化时传递一组插件来加载,这最终使整个事情变得非常简单。

框架/服务器

/**
 * Configures the Node.js Server.
 * @type {*}
 */

var _ = require('underscore'),
    express = require('express'),
    app = express(),
    port = process.env.PORT || 3003;

module.exports = {

    /**
     * Starts the connector multi server.
     * @param {Object} options A hash of options to configure the multi server.
     * @param {Array} options.connectors An array of multi server connectors to load.
     */
    start: function (options) {

        // Sanitize the options
        options = options || {connectors: []};

        // Configure express
        console.log('Configuring express...');
        require('./config/config.js')(app, express);
        require('./config/http-error.js');

        // Load controllers
        console.log('Loading controllers...');
        require('./controllers/appsecute.js')(app);
        require('./controllers/oauth2-client.js')(app);

        // Load connectors
        console.log('Loading connectors...');
        _.each(options.connectors, function (connector) {
            connector(app);
        });

        // Connectors have been loaded, start the multi server
        console.log('Finished loading connectors.');
        console.log('Starting multi connector server...');

        var express_app = app.listen(port);
        console.log("Multi connector server listening on port %d", port);
        return express_app;
    }
};

将框架 + 插件拉到一起进行部署的部署存储库

/**
 * A basic wrapper around the multi server that includes specific connector implementations ready for deployment.
 *
 * To add a new connector to the deployment:
 *  1. Add it as a dependency in package.json
 *  2. Pass it to the multi connector start() call.
 */
require('appsecute-connector-multi').server.start({
    connectors: [
        require('appsecute-connector-multi-heroku'),
        require('appsecute-connector-multi-tender'),
        require('appsecute-connector-multi-circleci'),
        require('appsecute-connector-multi-zendesk'),
        require('appsecute-connector-multi-github'),
        require('appsecute-connector-multi-travisci')
    ]
});

这样做的好处是除了简单之外,因为框架和所有单独的插件都被指定为部署项目中 package.json 中的依赖项,NPM 负责拉下所有共同依赖项,正如您所期望的那样:)

于 2013-04-13T22:13:55.597 回答