Что такое require и module.exports

Reading time ~5 minutes

Данная статья является прочтением и переосмыслением перевода Node.js, Require и Exports статьи-оригинала Node.js, Require and Exports.

Помимо этого, существует еще одна неплохая статья, посвященная данной тематике - Understanding module.exports and exports in Node.js.

Тематика данного поста посвящена двум командам Node.js -

1
require
и
1
module.exports
. Обе эти команды являются служебными и “принадлежат” Node.js.

С помощью этих команд Node.js осуществляет взаимодействие своих модулей между друг другом.

Команда

1
require
подключает один модуль к другому. Команда
1
module.exports
делает модуль доступным для других модулей.


Ниже - краткое изложение статьи-оригинала …

В Node.js все штуки видны друг другу только в рамках одного и того же файла. Под штуками я подразумеваю переменные, функции, классы и их члены.

Например, у нас есть файл

1
misc.js
следующего содержания:

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

Привычный доступ к константе

1
x
и переменной
1
summ
из другого файла невозможен. Это никак не связано с использованием
1
var
.

Дело в том, что Node.js состоит из блоков, называемых модулями; и каждый отдельный файл по своей сути — отдельный блок (модуль), чья область видимости изолирована от других таких же блоков (модулей).

Теперь перед тем как мы узнаем, как сделать эти штуки видимыми вне модуля, рассмотрим более подробно, как загружаются модули в Node.js.

Сейчас речь пойдет о том месте, где пишется -

1
require
. Служебное слово
1
require
используют для загрузки модуля, обычно присваивая результат его работы какой-то переменной:

let someModule = require('./some_module');

Другими словами можно сказать, что в Node.js служебное слово

1
require
служит для подключения одного независимого модуля (файла) к другому независимому модулю (файлу). Принцип подключения через
1
require
заключается в создании в целевом модуле объекта и помещении в этот объект подключаемого модуля.

Конечно же, до тех пор, пока наш модуль (

1
some_module
) ничего не отдает, все приведенные примеры бесполезны.

А чтобы наш модуль (

1
some_module
) что-нибудь отдал, мы будем использовать служебное слово
1
module.exports
:

const x = 5;
let summ = function (value) {
  return value + x;
};
module.exports.x = x; // сделали константу 5 доступной из других модулей
module.exports.summ = summ; // сделали переменную summ доступной из других модулей

Вот теперь наш модуль (

1
some_module
) стал гораздо более полезным:

let someModule = require('./some_module');

В результате в целевом модуле будет создан объект

1
someModule
со свойством
1
x = 5
(
1
someModule.x
) и методом
1
summ
(
1
someModule.summ
).

Есть ещё такой способ отдать штуки из нашего модуля:

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

То есть, в исходном модуле создается объект

1
User
со свойствами
1
User.name
и
1
User.email
. Затем с помощью служебного слова
1
module.exports
объект
1
User
делается доступным для других модулей Node.js.

Разница между этими подходами не велика, но важна. Как видно, в данном случае мы экспортируем функцию напрямую:

module.exports.User = User;

// vs

module.exports = User;

Всё это к тому, что потом ее будет легче использовать:

var user = require('./user');

var u = new user.User();

// vs

var u = new user();

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

Чтобы еще более красочно представить процесс взаимодействия модулей, давайте рассмотрим следующий пример:

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

Когда вы подключите данный модуль используя

1
require
, фактически им будет являться функция, что позволит вам сделать следующее:

let someModule = require('./powerlevel')(9000);

Что, по сути, является упрощенной записью следующего кода:

let someModule = require('./powerlevel');
someModule(9000);

Это все кратко о командах

1
require
и
1
module.exports
.

VSC - explorer.compactFolders

В Visual Studio Code по умолчанию стоит настройка, которая отображает на владке Explorer вложенные папки таким образом:![VSC - Default Vi...… Continue reading

Flattering operators

Published on July 12, 2024

Оператор withLatestFrom

Published on July 03, 2024