简体   繁体   English

node.js配置子模块

[英]node.js configure submodules

[EDIT] [编辑]

Thanks to Stafano that formalized my question in a better way: You have a module 感谢Stafano,他以更好的方式将我的问题正式化了:您有一个模块

-) There are several files in this module -)此模块中有几个文件

-) All these files depend on a configuration whose path is unknown to the module itself -)所有这些文件都依赖于模块本身未知路径的配置

-) This module does not do much on its own, and is meant to be used by other applications -)这个模块本身并不能做很多事情,并且可以被其他应用程序使用

-) These applications should inject a configuration path into the module before it can be used -)这些应用程序应该在使用模块之前向其注入配置路径

So i have this module, used from another application. 所以我有这个模块,可以从另一个应用程序中使用。 It's composed of other submodules and i want to configure it using a configuration object. 它由其他子模块组成,我想使用配置对象对其进行配置。 I already tried to inject the configuration in my submodels but i had the same problem exposed in the original question. 我已经尝试将配置注入我的子模型中,但是原始问题中暴露了同样的问题。

For example my module use mongoDB (with mongoose) as a store. 例如,我的模块使用mongoDB(带有mongoose)作为存储。

// app.js
// in the config object i have the URI to the mongo instance (in order to create a connection).
var myModule = require('myModule')(config);

// myModule.js
// files
// myModule/index.js expose the module's functionalities
// is the entry point so I create the mongoose connection
var mongoose = require('mongoose');
module.exports = function(config){
  var connection = mongoose.createConnection(config.store.URL);
  // I need to expose this connection to the others submodules.
}

// myModule/storeController.js contains the business logic that use the store (createItem, deleteItem, get...) and requrie mongoose and my Models (store in the models folder)
var mongoose = require('mongoose');
var Item     = require('./models/item.js');

exports.createItem = function(item){
  Item.save(item, function(err, item){
    if (err) throw
    ...
  });
} 

// myModule/models/item.js

// In this module i need to use the connection application in the configuration.
var mongoose = require('mongoose');
var connection = // i don't know how to get it

var ItemSchema = new mongoose.Schema({
  name: String
});

module.exports = mongoose.model('item', ItemSchema);

If I inject the configuration obj to the item.js i can't do the module.exports of my model. 如果我将配置obj注入item.js,则无法执行模型的module.exports。 I hope that this example can clarify my question, but the problem is the simple, expose an object after get it as a parameter. 我希望这个例子可以澄清我的问题,但是问题很简单,在获得对象作为参数后公开对象。

[PREVIOUS] I have a node.js application that require a module. [上一页]我有一个需要模块的node.js应用程序。 This module accept the coniguration file path (a JSON file). 此模块接受配置文件路径(JSON文件)。 I need to load that configuration on require and expose it to the module. 我需要按需加载该配置,并将其公开给模块。

How can I achieve this behavior? 我该如何实现这种行为?

Something like: 就像是:

// app.js
var myModule = require('myModule')(__dirname + '/config/myModuleCnfig.json');

// myModule.js

module.exports = function(configPath){
  var config = require(configPath);
  module.exports = config;  // This is wrong
}

Is there another way to get the configuration path, configure the module and share the configuration?? 还有另一种获取配置路径,配置模块并共享配置的方法吗?

With "share the configuration" i mean that i want to give the possibility to other files of my module to use that configuration. “共享配置”是指我想让模块的其他文件可以使用该配置。

Thanks for any suggestions! 感谢您的任何建议!

FINAL EDIT: 最终编辑:

After many misunderstandings, your problem is finally clear to me. 经过许多误会,我终于明白了您的问题。 To summarise what's in the comments, here is the situation: 总结评论中的内容,情况如下:

  • You have a module 你有一个模块
  • There are several files in this module 此模块中有几个文件
  • All these files depend on a configuration whose path is unknown to the module itself 所有这些文件都依赖于模块本身未知路径的配置
  • This module does not do much on its own, and is meant to be used by other applications 该模块本身并不能做很多事情,并且打算由其他应用程序使用
  • These applications should inject a configuration path into the module before it can be used 这些应用程序应该在使用模块之前向其注入配置路径

Since you cannot modify dynamically what a module exports, you should use another approach. 由于无法动态修改模块导出的内容,因此应使用另一种方法。 As with most situations that you encounter in programming, there is not one way which is always right, as much pedends on your requirements and limitations. 与您在编程中遇到的大多数情况一样,没有一种方法总是对的,这取决于您的要求和限制。

The easiest way to do this (which I don't recommend) is to use a global variable, which you set in your myModule.js file and will be used by the other files in your module. 执行此操作最简单的方法(不建议这样做)是使用全局变量,该变量是在myModule.js文件中设置的,并将由模块中的其他文件使用。 The biggest drawback of this approach is that you wouldn't be able to use multiple instances of the module at the same time with different configurations. 这种方法的最大缺点是,您将无法同时使用不同配置的模块的多个实例。 Also, any other module could easily modify (deliberately or not) you configuration at any time, by simply changing the value of the global variable, so it's also a security risk. 此外,任何其他模块都可以通过简单地更改全局变量的值来随时轻松地(有意或无意)修改您的配置,因此这也存在安全风险。

A much better way, which will probably require more work on your part - depending on how many files you have - is to implement some kind of Inversion of Control (IoC) . 更好的方法(这可能需要您做更多的工作-取决于您有多少文件)是实现某种控制反转(IoC) In your case, you could turn all your exports into functions that accept a config, and then initialise them by passing the active configuration after you require the module. 在您的情况下,您可以将所有导出转换为接受配置的函数,然后在需要模块后通过传递活动配置来对其进行初始化。 I don't know the specifics of your implementation, so here is some sample code: 我不知道您的实现细节,因此这里有一些示例代码:

// submodule1.js
module.exports = function(config) {
    // return something that uses the configuration
}

// myModule.js
var fs = require('fs');
var submodule1 = require('./submodule1');
var submodule2 = require('./submodule2');
// ...
module.exports = function(configPath){
    var config = JSON.parse(fs.readFileSync(configPath));
    var sm1 = submodule1(config);
    var sm2 = submodule2(config);
    return /* an object that uses sm1 and sm2 */; 
}

If your module is quite complex, you can use some IoC library that does the binding for you. 如果您的模块非常复杂,则可以使用一些IoC库为您执行绑定。 An good one could be Electrolite . 一个很好的可能是Electrolite

Hope this helps. 希望这可以帮助。

PREVIOUS ANSWER: 上一个答案:

You can use a library called jsop : 您可以使用一个名为jsop的库:

var jsop = require('jsop');
var config = jsop('./config/myModuleCnfig.json');

If you don't want to add a dependency to this module, the linked GitHub page also has a snippet that you can use to load the json config using only native methods. 如果您不想向该模块添加依赖项,则链接的GitHub页面上还有一个片段,您可以使用该片段仅使用本机方法来加载json配置。

EDIT: I just realised that this module is only for node 0.11, which you are probably not using. 编辑:我刚刚意识到,此模块仅用于节点0.11,您可能没有使用。 Since you don't probably need the writing functionality, you can use the following snippet instead: 由于您可能不需要编写功能,因此可以改用以下代码段:

var fs = require('fs')
var config = JSON.parse(fs.readFileSync('./config/myModuleCnfig.json'))

EDIT 2: 编辑2:

Now I think I understand your problem better. 现在我想我更好地了解了您的问题。 To pass the path to the required configuration, you can do something like this: 要将路径传递到所需的配置,可以执行以下操作:

// myModule.js

var fs = require('fs')
module.exports = function(configPath){
    var config = JSON.parse(fs.readFileSync(configPath))
    return config;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM