Когда я впервые начал играть с node.js, меня всегда беспокоила одна вещь. Как ни странно, я говорю о module.exports. Я говорю стыдно, потому что это фундаментальная часть node.js и довольно простая.

На самом деле, оглядываясь назад, я понятия не имею, что у меня было за трубку ... Я просто помню, что не мог понять этого. Если предположить, что я не единственный, кому пришлось взять второй и третий, посмотреть на него, прежде чем он, наконец, начал осваиваться, я подумал, что могу сделать небольшую запись .

В Node вещи видны только другим объектам в том же файле. Под вещами я имею в виду переменные, функции, классы и члены классов. Итак, дан файл misc.js со следующим содержанием:

const x = 5;
const addX = function(value) {
  return value + x;
};

Другой файл не может получить доступ к x переменной или addX функции. Это не имеет ничего общего с использованием ключевого слова const. Скорее, фундаментальный строительный блок Node называется модулем, который отображается непосредственно в файл. Таким образом, мы могли бы сказать, что указанный выше файл соответствует модулю с именем file1, и все в этом модуле (или любом модуле) является частным.

Теперь, прежде чем мы посмотрим, как открывать объекты вне модуля, давайте посмотрим на загрузку модуля. Здесь на помощь приходит require. require используется для загрузки модуля, поэтому его возвращаемое значение обычно присваивается переменной:

const misc = require('./misc');

Https://media.giphy.com/media/3ohhwoWSCtJzznXbuo/giphy.gif

Конечно, пока наш модуль ничего не раскрывает, все вышесказанное не очень полезно. Чтобы раскрыть то, что мы используем module.exports, и экспортировать все, что мы хотим:

const x = 5;
const addX = function(value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

Теперь мы можем использовать наш загруженный модуль:

var misc = require('./misc');
console.log("Adding %d to 10 gives us %d", misc.x, misc.addX(10));

Есть еще один способ раскрыть объекты в модуле:

var User = function(name, email) {
  this.name = name;
  this.email = email;
};
module.exports = User;

Разница небольшая, но важная. Видеть это? Мы экспортируем user напрямую, без какого-либо косвенного обращения. Разница между:

module.exports.User = User;
//vs
module.exports = User;

все о том, как это используется:

const user = require('./user');
const u = new user.User();
//vs
const u = new user();

Во многом зависит от того, является ли ваш модуль контейнером экспортируемых значений или нет. Фактически вы можете смешивать их в одном модуле, но я думаю, что это приведет к довольно уродливому API.

Наконец, последнее, что нужно учитывать, - это то, что происходит, когда вы напрямую экспортируете функцию:

const powerLevel = function(level) {
  return level > 9000 ? "it's over 9000!!!" : level;
};
module.exports = powerLevel;

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

require('./powerlevel')(9050);

Что на самом деле является сокращенной версией:

const powerLevel = require('./powerlevel')
powerLevel(9050);

Надеюсь, это поможет!