2013-03-27 2 views
0

Я хочу загрузить некоторые данные в файл server.js, который хранится в /data/projects.js (или .json в зависимости от ответа на вопрос).Node.js Лучший способ загрузить переменную JS синхронно

Я вижу две возможности:

  1. с использованием readFileSync:

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

    и projects.json будучи традиционным JSon файле

  2. использованием требуют:

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

    с projects.js, содержащих:

    exports.projects = { 
        // My variable 
    }; 
    

Вопрос в том, какой из них лучше:

  • с точки зрения производительности?
  • с точки зрения удобочитаемости узла/философии? (например, require() зарезервировано для модулей)

Я бы предположил, что решение 2 лучше, поскольку require(), вероятно, оптимизирован для чтения JS-кода, тогда как решение 1 должно прочитать файл, а затем проанализировать его, но разбор его может быть дешевле, чем его выполнение.

ответ

1

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

. js-файлы интерпретируются как текстовые файлы JavaScript, а файлы .json анализируются как текстовые файлы JSON. .node интерпретируются как скомпилированные модули аддона, загружаемые с помощью dlopen.

Так что я бы сделал require("./data/projects.json"), так как он является самым коротким и, по-видимому, оптимизирован довольно хорошо.

Laurent делает хорошее замечание: результат запроса кэшируется.Это может быть преимуществом или недостатком. Если вы прочитаете файл только один раз, когда начнется ваше приложение, это не имеет значения.

Это как узел делает это (кроме кэширования результата):

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

3

Основная причина использования функций sync fs в node.js - это загрузка файлов до запуска вашего приложения. Наиболее распространенной причиной является загрузка конфигурационного файла. В этом случае производительность не имеет значения.

Это, как говорится, основное различие между readFileSync и require заключается в том, что требуется кэшировать содержимое файла. Я видел бесчисленные раз require, используемые для загрузки json-файла, поэтому я не думаю, что он зарезервирован для модулей (обязательно укажите .json в пути к файлу).

Наконец, не забудьте, что вы можете использовать module.exports = {..}, если хотите написать var projects = require('./data/projects.js');.

EDIT: Для справки, я проверил исходный код 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

Я обычно обернуть мой внешний конфигурационный файл в-среды в модуле, который управляет значения по умолчанию, системные переменные, и т. д., поэтому я использую как 'require' *, так и' 'readFileSync' –

Смежные вопросы