2013-10-01 9 views
0

В моем узле приложении, есть конфигурационный файл, как это:Не изменяя груженый узел модуля

module.exports = { 
    BUILD_DIR: '/some.path', 
    OTHER_CONFIG: 42, 
    // ... 
}; 

У меня также есть некоторые тесты, делать такие вещи, как

var appConfig = require('./path/to/appConfig'); 
appConfig.BUILD_DIR = 'tmp/some/path'; 
// and stuff done with appConfig 

К моему большому удивлению, делая это, по-видимому изменяет состояние модуля. Мой следующий тест, который требует этого, будет иметь BUILD_DIR, установленный в 'tmp/some/path'. Я не понимал, что модули требуют такого состояния. Как мне избавиться от этого эффекта в моем тесте? Кроме того, как я могу запретить людям изменять состояние этого модуля? Если кто-то включает его, они всегда должны получать то, что он определяет, и, возможно, что-то еще не написал какой-то другой код.

ответ

1

Причина is explained here:

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

(курсив мой)

Так объект, который вы экспорт кэшируются и распределяются между кодом, который использует его.

Если это не то, что вы хотите, вы можете экспортировать функцию вместо:

module.exports = function() { 
    return { 
    BUILD_DIR: '/some.path', 
    OTHER_CONFIG: 42, 
    // ... 
    }; 
}; 

И require это так:

var appConfig = require('./path/to/appConfig')(); 
+0

Это на самом деле не работает, я до сих пор в конечном итоге с моей модификации, показывая в моем другом тесте. Если я делаю «return extend ({}, {..config ..})» в функции, то это действительно работает. –

+1

Я протестировал его, и он работает для меня ([gist] (https://gist.github.com/robertklep/c58a3da939d6c18d07aa)). Он должен, потому что объект, возвращаемый функцией, вновь создается каждый раз, когда вызывается функция, даже если сама функция кэшируется. – robertklep

+0

Ах, действительно. Я помещал конфигурацию в var, а затем возвращал ее через функцию. Выполнение этого за один шаг работает так, как рекламируется. –

1

Предполагая, что ваш модуль называется «Config», и первоначально :

var Config=require('Config'); 

вы можете:

delete require.cache[require.resolve('Config')]; 

, который удалит модуль из кеша потребности, в результате чего он будет загружен заново, когда вы будете «требовать» его.

Gist: https://gist.github.com/raisch/6786930

+0

Интересно. Это, однако, несет ответственность со всеми вызывающими абонентами, чтобы сделать это, когда это необходимо. Бит-ошибка подвержена ошибкам, и вызванные ошибки, вероятно, не будут очень локальными. –

+0

На самом деле, единственный эффект от выполнения вышеизложенного - это возможность перезагрузить модуль. Исходная нагрузка по-прежнему доступна после удаления кеша, поэтому единственным возможным побочным эффектом будет то, что вы изменили что-то особенно важное для работы системы несовместимым образом. –

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