Node.js动态更改导出

时间:2014-07-04 18:23:05

标签: javascript node.js

在函数中更改exports.X似乎不起作用...

我希望能够从文件和文件中加载设置。在Node.js中访问它们我目前有这个,但是,连接到我的节点应用程序的客户端可以编辑设置文件中的内容。不幸的是,必须重新启动Node应用程序才能使更改生效。有没有办法可以动态重新加载module.exports?

编辑:

设置文件实际上是一个JSON字符串。

我的设置模块几乎在每个文件中都是“必需的”,并且有很多文件...因此,基于每个文件重新加载它是不可能的。但是,我确切知道有人对设置进行了更改。

2 个答案:

答案 0 :(得分:2)

如果您使用require加载设置并仅引用一个模块中的设置,那么请执行以下操作:

delete require.cache[require.resolve(filename)];

会为你效劳。

另一方面,如果多个模块将引用这些设置,那么这种方法可能会变得有点笨拙并且让您无法预料的错误。例如,如果任何模块持有对所需设置文件的引用,则每个模块都需要以某种方式了解设置已更改并更新其引用。

为缓解(不完全解决)缓存问题,您需要构建设置界面,以便其用户必须通过函数访问设置对象和/或要求通过函数访问属性。即使使用这种模式,有人可能仍然会决定缓存一个设置,导致后来发生的模糊故障。

对设置对象使用单个getter的最简单方法看起来像这样:

var settings = require('./settings.json');

// ... watch for changes and reload by invalidating node's cache

module.exports = function() { return settings; }

用法:

var settings = require('./path/to/settings');

settings().foo;

有几个库可以进行设置。根据您的需要,我偏向nconf

答案 1 :(得分:0)

我在这里设置了一个文件监视器,可以动态检查JSON文件的变化。一旦应用程序运行,建议不要更改JS脚本。

类似的东西:

var _ = require("lodash");
var fs = require("fs");
var result = {};

fs.watch('my-settings.json',function(event,filename){
   fs.readFile(filename,function(err,data){
       if(err){
          // your error catching
       }
       _.extend(result,JSON.parse(data));
   });
});

module.exports = result;

现在,这有很多警告,首先,所有平台并不总是支持fs.watch。 http://nodejs.org/api/fs.html#fs_fs_watch_filename_options_listener

其次,改变像这样的房产真的很尴尬。期望通常是模块的输出不变异。我建议公开一种方法,该方法的结果可以根据文件的状态而改变,这是结果数据的getter。

第三,文件监视器在内存方面可能很昂贵。

这是更好的代码,恕我直言:

var _ = require("lodash");
var fs = require("fs");
var filename = 'my-settings.json';
var lastModified;
var mySetting;    

module.exports = {
    getSettingAsync : function (callback) {
        fs.stat(filename,function(err,stat){
            if(stat.mtime == lastModified) {
                callback(mySetting);
            } else {
                fs.readFile(filename,function(err,data){
                   if(err){
                      // your error catching
                   }

                   // this assumes that your data is always correct
                   mySetting = JSON.parse(data).mySetting;

                   callback(mySetting);
               });
            }
        });
    }
};

在这种情况下,我们都检查JSON文件,并将其作为异步方法公开。如果需要,您可以轻松地更改代码以使用同步版本并返回值而不是调用回调。此版本检查文件何时更改,这比每次读取整个文件便宜,如果更新则读取文件并节省您使用可能有错误的文件观察程序的需要。

顺便说一下,我没有测试过这段代码,它可能包含错误,但概念很合理。

但是,也许更为突出的问题是,为什么不将该值存储在数据库中呢?