Есть три куска кода:
index.js
const module1 = require('./1');
const module2 = require('./2');
1.js
const methods = require('./2');
console.log('hello from 1');
console.log('1', methods);
module.exports = {
foo() {console.log('one')},
test() {console.log(module)},
};
2.js
const methods = require('./1');
console.log('hello from 2');
console.log('2', methods);
setTimeout(() => {
console.log(methods);
}, 1000);
module.exports = {
foo() {console.log('two')},
test() {console.log(module)},
};
Подскажите пожалуйста, почему в консоли после выполнения таймаута, выведет пустой объект ? И если поменять в 1.js строки с экспортом модуля на
module.exports.foo = function() {console.log('foo')};
module.exports.test = function() {console.log(module)};
, то в консоли выведет заполненный объект функцией foo и содержимым модуля? В спецификации написано, что module не является глобальным объектом. Тогда почему происходит перезаписывание ?
https://nodejs.org/api/modules.html#modules_cycles
Потому что когда вы из модуля 2 вызвали модуль 1, он вернул дефолтный объект module.exports, который создаётся нодов при инициализации модуля.
Позже вы заменили его на другой объект (module.exports = {...}), но модуль 2 уже закешировал неактуальную копию.
Поэтому надо избегать таких циклов, а если по каким-то причинам так сделать не получается, то не заменять module.exports, а добавлять методы в него.
Например можно сделать так:
// 1.js
const methods = require('./2');
console.log('hello from 1');
console.log('1', methods);
Object.assign(module.exports, {
foo() {console.log('one')},
test() {console.log(module)},
});
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники