Основы работы с Node.js

Модули

Последнее обновление: 21.11.2023

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

При необходимости мы можем подключать нужные нам модули. Какие встроенные модули есть в node.js и какую функциональность они предоставляют, можно узнать из документации.

Вообще в мире JavaScript есть различные системы модулей. По умолчанию Node.js применяет систему модулей CommonJS, которая рассматривает отдельный файл как модуль, для загрузки модулей применяет функцию require(), в которую передается название модуля. К примеру, в первом приложении из предыдущей темы для получения и обработки запроса был необходим модуль http:

const http = require("http");

После получения модуля мы сможем использовать весь определенный в нем функционал, который опять же можно посмотреть в документации.

Подобным образом мы можем загружать и использовать другие встроенные модули. Например, используем модуль os, который предоставляет информацию об окружении и операционной системе. Для этого определим файл app.js со следующим кодом:

const os = require("os");
// получим имя текущего пользователя
const userName = os.userInfo().username;

console.log(userName);

Запустим это приложение командой node app.js, и на консоль будет выведено имя текущего пользователя:

c:\app> node app.js
Eugene
c:\app>

Создание своих модулей

Мы не ограничены встроенными модулями и при необходимости можем создать свои. Так, добавим в каталог приложения (где находится файл app.js) новый файл greeting.js и определим в нем следующий код:

console.log("Hello METANIT.COM");

В файле app.js подключим наш модуль:

const greeting = require("./greeting");

В отличие от встроенных модулей для подключения своих модулей надо передать в функцию require относительный путь с именем файла (расширение файла необязательно). Запустим приложение:

c:\app> node app.js
Hello METANIT.COM
c:\app>

На консоль выводится та строка, которая определена в файле greeting.js.

Стоит отметить, что внутри модуля с помощью специального объекта module мы можем получить инфрмацию о модуле. Например, изменим файл greeting.js следующим образом:

console.log(module);

Повторно запустим файл app.js. В моем случае вывод будет следующим:

c:\app> node app.js
{
  id: '/Users/eugene/Documents/app/greeting.js',
  path: '/Users/eugene/Documents/app',
  exports: {},
  filename: '/Users/eugene/Documents/app/greeting.js',
  loaded: false,
  children: [],
  paths: [
    '/Users/eugene/Documents/app/node_modules',
    '/Users/eugene/Documents/node_modules',
    '/Users/eugene/node_modules',
    '/Users/node_modules',
    '/node_modules'
  ]
}
c:\app>

Здесь мы видим, что объект module содержит ряд свойств, которые позволяют получить каталог и путь к файлу текущего модуля, а также пути, где будет идти поиск модулей.

Экспорт из модуля

Теперь определим в модуле greeting.js какое-нибудь более интересное содержимое. Что может определять модуль? По сути модуль - это обычный файл кода javascript, который может определять переменные, константы, функции, вызывать свои и другие функции. Например, изменим файл greeting.js следующим образом:

const currentDate = new Date();

// в зависимости от часа выводим определенное сообщение
function printMessage(name){
    const hour = currentDate.getHours();
    if(hour > 16)
        console.log("Добрый вечер,", name);
    else if(hour > 10)
        console.log("Добрый день,", name);
    else
        console.log("Доброе утро,", name);
}

Здесь определена константа currentDate, которая хранит текущую дату. Также определена функция printMessage, в которую передается имя пользователя, и в зависимости от текущего часа выводится то или иное сообщение.

Мы можем использовать константу date и функцию printMessage внутри модуля greeting.js, однако извне они не доступны. Для проверки доступности в файле app.js выведем модуль greeting на консоль:

const greeting = require("./greeting");
console.log(greeting); // {}

Запустим файл app.js

c:\app> node app.js
{}
c:\app>

Мы видим, что модуль greeting представляет пустой объект. Но в реальности в нем определена константа и функция. И чтобы получить их в других модулях, их надо экспортировать. Для этого изменим файл greeting.js следующим образом:

const currentDate = new Date();
exports.date = currentDate;  // экспортируем константу currentDate под именем date

// экспортируем функцию
exports.printMessage = function (name){
    const hour = currentDate.getHours();
    if(hour > 16)
        console.log("Добрый вечер,", name);
    else if(hour > 10)
        console.log("Добрый день,", name);
    else
        console.log("Доброе утро,", name);
}

Чтобы какие переменные/константы или функции модуля были доступны, необходимо определить их в объекте module.exports. Объект module.exports - это то, что возвращает функция require() при получении модуля.

В частности, здесь определяется свойство exports.date, которое хранит значение currentDate, и свойство exports.printMessage, которое хранит функцию.

Далее изменим файл app.js:

const os = require("os");
const greeting = require("./greeting");

// имя текущего пользователя
const userName = os.userInfo().username;

console.log(`Дата запроса: ${greeting.date}`);
greeting.printMessage(userName);

Все экспортированные переменные/константы и функции доступны через свойства, которые были установлены при экспорте - greeting.date и greeting.printMessage.

Перезапустим приложение. В моем случае я получу следующий результат:

c:\app> node app.js
Дата запроса: Tue Nov 21 2023 18:23:06 GMT+0300 (Москва, стандартное время)
Добрый вечер, Eugene
c:\app>

Импорт компонентов модуля

В примере выше мы импортировали всю функциональность модуля как единое целое и через имя greeting могли обращаться к этой функциональности:

const greeting = require("./greeting");

Однако также мы можем импортировать компоненты по отдельности:

// получаем компоненты модуля  по отдельности
const {date, printMessage} = require("./greeting");

// имя текущего пользователя
const userName = "Tom";

console.log(`Дата запроса: ${date}`);
printMessage(userName);

Здесь для получения компонентов модуля указываем их имена в фигурных скобках

const {date, printMessage} = require("./greeting");

Передаваемые имена - имена объектов, установленных при экспорте. После этого можно использовать имена этих компонентов без имени модуля:

printMessage(userName);

Необязательно получать все компоненты. Можно получать только некоторые, которые мы собираемся использовать:

// получаем только функцию printMessage 
const {printMessage} = require("./greeting");
// или так
// const printMessage = require("./greeting").printMessage;

const userName = "Tom";
printMessage(userName);

Можно определить свое имя для компонента модуля:

// функция print представляет функцию из printMessage
const print = require("./greeting").printMessage;

const userName = "Bob";
print(userName);

Определение конструкторов и объектов в модуле

Кроме определения простейших функций или свойств в модуле могут определяться сложные объекты или функции конструкторов, которые затем используются для создания объектов. Так, добавим в папку проекта новый файл user.js:

function User(name, age){
     
    this.name = name;
    this.age = age;
    this.print = function(){
        console.log(`Имя: ${this.name}  Возраст: ${this.age}`);
    }
}
User.prototype.sayHi = function() {
    console.log(`Привет, меня зовут ${this.name}`);
};
 
module.exports = User;

Здесь определена стандартная функция конструктора User, которая принимает два параметра. При этом весь модуль теперь указывает на эту функцию конструктора:

module.exports = User;

Подключим и используем этот модуль в файле app.js:

// получаем только функцию printMessage
const User = require("./user.js");

const eugene = new User("Eugene", 22);
eugene.print();
eugene.sayHi();

Запустим приложение:

c:\app> node app.js
Имя: Eugene  Возраст: 22
Привет, меня зовут Eugene
c:\app>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850