В основном ответ заключается в том, что действительно происходит, когда модуль требуется с помощью оператора require
.Предполагая, что это первый раз, когда требуется модуль.
Например:
var x = require('file1.js');
содержимое файла file.js:
module.exports = '123';
Когда приведенный выше операторвыполнено, объект Module
создан.Его функция конструктора:
function Module(id, parent) {
this.id = id;
this.exports = {};
this.parent = parent;
if (parent && parent.children) {
parent.children.push(this);
}
this.filename = null;
this.loaded = false;
this.children = [];
}
Как видите, у каждого объекта модуля есть свойство с именем exports
.Это то, что в итоге возвращается как часть require
.
Следующий шаг require - это обернуть содержимое file1.js в анонимную функцию, как показано ниже:
(function (exports, require, module, __filename, __dirname) {
//contents from file1.js
module.exports = '123;
});
И этоанонимная функция вызывается следующим образом, module
здесь относится к Module
объекту, созданному ранее.
(function (exports, require, module, __filename, __dirname) {
//contents from file1.js
module.exports = '123;
}) (module.exports,require, module, "path_to_file1.js","directory of the file1.js");
Как мы можем видеть внутри функции, exports
формальный аргумент ссылается на module.exports
.По сути, это удобство, предоставляемое программисту модуля.
Однако с этим удобством нужно обращаться осторожно.В любом случае, если вы пытаетесь назначить новый объект для экспорта, убедитесь, что мы делаем это следующим образом.
exports = module.exports = {};
Если мы сделаем это следующим образом неправильный путь , module.exports
по-прежнему будет указыватьк объекту, созданному как часть экземпляра модуля.
exports = {};
В результате добавление чего-либо к указанному выше объекту экспорта не повлияет на объект module.exports, и ничего не будет экспортировано или возвращено как часть require.