Node.js同步加载JS变量的最佳方法

时间:2013-03-27 08:36:24

标签: javascript json performance node.js

我想在server.js文件中加载一些存储在/data/projects.js(或.json中的数据,取决于问题的答案)。

我看到两种可能性:

  1. 使用readFileSync:

    function readJsonFileSync() {
        var file = fs.readFileSync(__dirname + '/data/projects.json', 'utf8');
        return JSON.parse(file);
    }
    

    和projects.json是传统的json文件

  2. 使用require:

    function readJsonFileReq() {
        return require('./data/projects.js')['projects'] ;
    }
    

    project.js包含:

    exports.projects = {
         // My variable
    };
    
  3. 问题是哪一个是最好的:

    • 在表现方面?
    • 在节点可写性/哲学方面? (例如,为模块保留require())

    我猜解决方案2更好,因为require()可能已经优化用于读取JS代码,而解决方案1必须读取文件,然后解析它,但解析它可能比执行它更便宜。

2 个答案:

答案 0 :(得分:3)

在node.js中使用sync fs函数的主要原因是在应用启动之前加载文件。最常见的原因是加载配置文件。在这种情况下,性能无关紧要。

话虽如此,readFileSyncrequire之间的主要区别在于require会缓存文件的内容。我已经看到无数次require用于加载json文件,所以我不认为它是保留给模块的(尽管确保在文件路径中包含.json)。

最后,如果你想写module.exports = {..},请不要忘记你可以使用var projects = require('./data/projects.js');

编辑:作为参考,我检查了node.js的源代码,并且怀疑require在内部使用了readFileSync

https://github.com/joyent/node/blob/master/lib/module.js#L472

// Native extension for .js
Module._extensions['.js'] = function(module, filename) {
  var content = NativeModule.require('fs').readFileSync(filename, 'utf8');
  module._compile(stripBOM(content), filename);
};

答案 1 :(得分:1)

http://nodejs.org/api/modules.html#modules_file_modules

  

.js文件被解释为JavaScript文本文件,.json文件被解析为JSON文本文件。 .node文件被解释为用dlopen加载的已编译的插件模块。

所以我会做require("./data/projects.json"),因为它是最短的,并且可能已经很好地优化了。

劳伦特做了一个很好的评论:要求的结果被缓存。这可能是优点或缺点。如果您在应用程序启动时只读取一次文件,则无关紧要。

这是节点的工作方式(除了缓存结果):

Module._extensions['.json'] = function(module, filename) {
 var content = NativeModule.require('fs').readFileSync(filename, 'utf8');
 try {
  module.exports = JSON.parse(stripBOM(content));
 } catch (err) {
   err.message = filename + ': ' + err.message;
   throw err;
 }
};

https://github.com/joyent/node/blob/master/lib/module.js#L479