Объекты exports, require и module глобально доступны в каждом файле, но каждый файл имеет их собственные экземпляры. Как такое возможно?
Этот вопрос проверяет понимание механизма модульной системы Node.js, а также концепции замыкания и функций-оберток.
Короткий ответ
Объекты exports, require и module не являются настоящими глобальными объектами. Node.js оборачивает каждый модуль (файл) в функцию-обертку, которая предоставляет каждому файлу его собственные версии этих объектов. Это изолирует модули друг от друга.
Длинный ответ
В Node.js каждый файл рассматривается как отдельный модуль. Когда файл загружается, Node.js автоматически оборачивает его содержимое в функцию-обертку вида:
(function (exports, require, module, __filename, __dirname) {
// Код модуля
});Эта функция:
- Создает изоляцию для модуля.
В результате каждый файл получает свои экземпляры exports, require, module, а также пути к текущему файлу (__filename) и директории (__dirname).
- Передает нужные объекты в качестве параметров.
Объект exports изначально пустой, а module содержит информацию о текущем модуле.
- Обеспечивает контроль за экспортом.
Объект exports — это ссылка на свойство module.exports. Вы можете либо добавлять свойства к exports, либо заменить его полностью через module.exports.
Пример:
// module1.js
console.log(exports); // {}
console.log(require); // Функция require
console.log(module); // Объект module
Фактически, код внутри каждого файла запускается как:
(function (exports, require, module, __filename, __dirname) {
console.log(exports, require, module);
})();Почему это важно:
- Изоляция: Код одного модуля не влияет напрямую на другой.
- Безопасность: Каждый модуль получает свои экземпляры объектов, предотвращая конфликты.
- Гибкость: Вы можете изменять или добавлять свойства к объекту exports, экспортируя функционал.
Заключение:
Каждый модуль в Node.js получает свои собственные экземпляры exports, require и module благодаря функции-обертке, которая изолирует файлы и предоставляет удобный способ работы с модулями.