Зачем нужен module.exports в Node.js и как его правильно использовать?
Что такое module.exports и как работает система модулей в Node.js
В Node.js каждый файл считается отдельным модулем. Переменные и функции, объявленные внутри файла, по умолчанию являются приватными — они видны только внутри этого файла. Система модулей основана на спецификации CommonJS, и module.exports — это специальный объект, который возвращается при вызове require().
Простейший пример экспорта
Исправим ваш math.js:
// math.js
function add(a, b) {
return a + b;
}
function multiply(a, b) {
return a * b;
}
// Экспортируем объект с функциями
module.exports = {
add: add,
multiply: multiply
};
Теперь в app.js:
// app.js
const math = require('./math.js');
console.log(math.add(2, 3)); // 5
console.log(math.multiply(2, 3)); // 6
require('./math.js') возвращает то, что было присвоено module.exports. В нашем случае — объект с двумя методами.
Разница между module.exports и exports
Изначально exports — это просто ссылка на module.exports. То есть: exports = module.exports. Поэтому можно писать:
// math.js (альтернативный синтаксис)
exports.add = function(a, b) {
return a + b;
};
exports.multiply = function(a, b) {
return a * b;
};
Это работает, потому что мы добавляем свойства к объекту, на который ссылается exports. Однако важно: нельзя переопределять exports целиком!
❌ Неправильно:
exports = {
add: add,
multiply: multiply
}; // module.exports останется пустым объектом!
✅ Правильно: используйте module.exports, если хотите присвоить новое значение (например, функцию или другой объект).
Когда использовать каждый подход
- Экспорт нескольких функций/значений: используйте
module.exports = { ... }илиexports.key = value. Первый способ нагляднее, если экспортируете много сущностей. - Экспорт одной функции или класса: используйте
module.exports = function() { ... }. Это позволяет импортировать модуль как функцию:
// logger.js
module.exports = function(message) {
console.log(`[LOG]: ${message}`);
};
// app.js
const log = require('./logger.js');
log('Hello!'); // [LOG]: Hello!
- Экспорт класса:
// user.js
class User {
constructor(name) {
this.name = name;
}
greet() {
return `Hi, I'm ${this.name}`;
}
}
module.exports = User;
// app.js
const User = require('./user.js');
const user = new User('Alice');
console.log(user.greet()); // Hi, I'm Alice
Почему не использовать глобальные переменные?
Глобальные переменные в Node.js — плохая практика, потому что:
- Они загрязняют глобальное пространство имён, что может привести к конфликтам.
- Усложняется отладка и тестирование кода.
- Нарушается принцип модульности — каждый модуль должен быть независимым.
Важное замечание про пути
В require() пути указываются относительно текущего файла. Для локальных модулей используйте:
./file— файл в той же папке../folder/file— файл в родительской папке
Без префикса ./ или ../ Node.js будет искать встроенный модуль или пакет из node_modules.
Дополнительный взгляд: типы экспорта и особенности
Кроме базового использования, стоит знать несколько тонкостей, которые помогут избежать ошибок.
Экспорт примитивов
Можно экспортировать не только объекты и функции, но и примитивные значения:
// config.js
module.exports = {
port: 3000,
dbUrl: 'mongodb://localhost:27017'
};
// Или просто число/строку
module.exports = 42;
Но обычно экспортируют объекты или функции для гибкости.
Проблема с циклическими зависимостями
Если модуль A требует модуль B, а модуль B требует модуль A, Node.js вернёт неполный объект. В таких случаях лучше реструктурировать код или отложить require внутрь функций.
Сравнение с ES-модулями (import/export)
Современный JavaScript (ES6+) использует синтаксис import/export. В Node.js он поддерживается с версии 12 (с флагом --experimental-modules) или в файлах с расширением .mjs. CommonJS (module.exports/require) остаётся стандартом для большинства проектов.
Практический совет
Для простоты придерживайтесь правила: если экспортируете одну сущность — используйте module.exports = ..., если несколько — exports.имя = ... или объект. И никогда не переопределяйте exports целиком, если не уверены в последствиях.
Ответов пока нет.
Войдите чтобы оставить ответ