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>