Понимание модhive Node.js: multiple требует возврата одного и того же объекта?

У меня есть вопрос, связанный с документацией node.js по кэшированию модhive :

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

Множественные вызовы, требуемые (‘foo’), не могут приводить к тому, что код модуля выполняется несколько раз. Это важная функция. С его помощью могут быть возвращены объекты с «частично выполненными», что позволяет загружать транзитивные зависимости, даже если они будут вызывать циклы.

Что имеется в виду с may ?

Я хочу знать, будет ли запрос всегда возвращать тот же объект. Поэтому в случае, если мне нужен модуль A в app.js и изменить объект экспорта в app.js (тот, который требует возврата), а после этого требуется модуль B в app.js который сам требует модуля A , всегда получаю ли я измененная версия этого объекта или новая?

 // app.js var a = require('./a'); ab = 2; console.log(ab); //2 var b = require('./b'); console.log(bb); //2 // a.js exports.a = 1; // b.js module.exports = require('./a'); 

Если оба app.js и b.js находятся в одном проекте (и в том же каталоге), то оба из них получат один и тот же экземпляр A Из документации node.js :

… каждый вызов require('foo') получит точно тот же объект , который был бы возвращен, если он разрешит один и тот же файл .


Ситуация различна, когда a.js , b.js и app.js находятся в разных модулях npm . Например:

 [APP] --> [A], [B] [B] --> [A] 

В этом случае require('a') в app.js разрешит другую копию a.js чем require('a') в b.js и, следовательно, возвращает другой экземпляр A Существует более подробное описание этого поведения в блоге .

node.js реализует какое-то кэширование, которое блокирует узел от чтения файлов 1000 раз, выполняя некоторые огромные серверные проекты.

Этот кеш указан в объекте require.cache . Я должен отметить, что этот объект читается / записывается, что дает возможность удалять файлы из кеша, не убивая процесс.

http://nodejs.org/docs/latest/api/globals.html#require.cache

Оух, забыл ответить на вопрос. Изменение экспортируемого объекта не влияет на следующую загрузку модуля. Это вызовет много проблем … Требовать всегда возвращать новый экземпляр объекта, без ссылки. Редактирование файла и удаление кеша изменяет экспортированный объект

После выполнения некоторых тестов node.js кэширует module.exports. Модификация require.cache[{module}].exports заканчивается в новом, измененном возвращенном объекте.

Для того, что я видел, если имя модуля разрешено для файла, загружаемого ранее, будет возвращен кешированный модуль, иначе новый файл будет загружен отдельно.

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

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

попробуйте drex : https://github.com/yuryb/drex

drex наблюдает за модулем для обновлений и после этого обновляет модуль после перезагрузки. Новый код требует () d, как если бы новый код был совершенно другим модулем, поэтому require.cache не является проблемой.

Если причина, по которой вы хотите, require(x) возвращать новый объект каждый раз только потому, что вы напрямую изменяете этот объект – это случай, с которым я столкнулся – просто клонируйте его и модифицируйте и используйте только клон, например:

 var a = require('./a'); a = JSON.parse(JSON.stringify(a)); 

Поскольку вопрос был опубликован, документ был обновлен, чтобы было понятно, почему «май» изначально используется. Теперь он отвечает на вопрос сам, делая вещи явными (мой акцент показывает, что изменилось):

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

При условии, что require.cache не будет изменен, несколько вызовов, требующих require (‘foo’) , не будут вызывать выполнение кода модуля несколько раз. Это важная функция. С его помощью могут быть возвращены объекты с «частично выполненными», что позволяет загружать транзитивные зависимости, даже если они будут вызывать циклы.