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

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

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

Несколько вызовов, требующих ('foo') , не могут вызывать код модуля выполняется несколько раз. Это важная функция. С этим, "частично выполненные" объекты могут быть возвращены, что позволяет зависимостей для загрузки, даже если они будут вызывать циклы.

Что подразумевается под may?

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

// app.js

var a = require('./a');
a.b = 2;
console.log(a.b); //2

var b = require('./b');
console.log(b.b); //2

// a.js

exports.a = 1;

// b.js

module.exports = require('./a');

Ответ 1

Если оба 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 than require('a') в b.js и, следовательно, вернет другой экземпляр A. Существует сообщение , описывающее это поведение более подробно.

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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