Работа с модулями в Node.js
Цель
В этом уроке мы разберем простой пример работы на Node.js, который будет включать в себя экспорт и импорт модулей.
Предварительныетребования
Знание основ JavaScript.
Классы и наследование в ES6 [1].
Установить Node.js и npm
Подключение модулей
Для подключения как собственных, так и сторонних модулей в Node.js используется функция require()
, которой нужно передать путь к файлу.
В зависимости от параметра, переданного в функцию require()
, отличается алгоритм подключения модуля. Полную информация по поводу подключения модулей можно найти в документации.
Рассмотрим базовые варианты подключения модулей:
Встроенные в Node.js модули подключаются по имени (например
const http = require('http')
) и имеют приоритет над всеми остальными. Так если будет сторонний модуль с таким названием или файл с таким именемrequire('http')
всегда вернет встроенный модуль.Сторонние модули, подключенные через NPM находятся в папке проекта
node_modules
. Если идентификатор модуля, переданныйrequire()
, не является основным модулем и не начинается с '/', '../' или './', то Node.js начинает искать в родительском каталоге текущего модуля папкуnode_modules
, и пытается загрузить модуль из этого места. Если он там не найден, он перемещается в родительский каталог и так далее, пока не будет достигнут корень файловой системы. Чтобы подключить модуль который находится вnode_modules
достаточно указать его название (const express = require('express')
). NPM также даем возможность установить модуль глобальноnpm install -g MODULE
, тогда он будет доступен из любого места.Рассмотрим еще один вариант подключения, если переданный параметр в функцию
require
начинается с /, ../, или ./, тогда файл для подключения будет происходить по абсолютному пути или относительно текущей папки. При этом тип файла указывать не надо, так как Node.js попытается сначало подключить файл с именем точно соответствующим указанному, а потом добавляя к имени разные расширения: .js, .json, а также .node. Пример подключения:const user = require('./user.js')
. Если в пути указан путь только к папке, то по умолчанию в этой папке будет искаться файл index.js. Чтобы изменить настройку по умолчанию необходимо в файле package.json изменить свойство "main".
Чтобы получить полный путь, по которому был найден модуль, можно воспользоваться функцией require.resolve()
.
var modulePath = require.resolve('express')
- запишет в переменную modulePath путь к модулю 'express'.
Объединяя все вышесказанное, вот алгоритм высокого уровня в псевдокоде того, что require.resolve()
делает:
require(X) from module at path Y
If X is a core module,
a. return the core module
b. STOP
If X begins with '/'
a. set Y to be the filesystem root
If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
b. LOAD_AS_DIRECTORY(Y + X)
LOAD_NODE_MODULES(X, dirname(Y))
THROW "not found"
LOAD_AS_FILE(X)
If X is a file, load X as JavaScript text. STOP
If X.js is a file, load X.js as JavaScript text. STOP
If X.json is a file, parse X.json to a JavaScript Object. STOP
If X.node is a file, load X.node as binary addon. STOP
LOAD_INDEX(X)
If X/index.js is a file, load X/index.js as JavaScript text. STOP
If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
If X/index.node is a file, load X/index.node as binary addon. STOP
LOAD_AS_DIRECTORY(X)
If X/package.json is a file,
a. Parse X/package.json, and look for "main" field.
b. let M = X + (json main field)
c. LOAD_AS_FILE(M)
d. LOAD_INDEX(M)
LOAD_INDEX(X)
LOAD_NODE_MODULES(X, START)
let DIRS=NODE_MODULES_PATHS(START)
for each DIR in DIRS:
a. LOAD_AS_FILE(DIR/X)
b. LOAD_AS_DIRECTORY(DIR/X)
NODE_MODULES_PATHS(START)
let PARTS = path split(START)
let I = count of PARTS - 1
let DIRS = []
while I >= 0,
a. if PARTS[I] = "node_modules" CONTINUE
b. DIR = path join(PARTS[0 .. I] + "node_modules")
c. DIRS = DIRS + DIR
d. let I = I - 1
return DIRS
Экспортирование модулей
Теперь разберемся с экспортированием собственных модулей. В Node.js есть несколько путей для экспортирования данных.
В каждом модуле доступен объект module
. Основная задача этого объекта дать возможность модулю вернуть результат своего исполнения. Это может быть и объект, и функция, и строка — любой тип данных.
У объекта module
есть свойство exports
, в которое можно добавить все, что необходимо вернуть из модуля. Именно module.exports
вернется как результат подключения модуля. Также вместо module.exports
можно использовать переменнуюexports.
Следующие строки будут эквивалентны:
module.exports.hello = true;
exports.hello = true;
Если вы хотите чтобы модуль возвращал не объект, с методами и свойствами, а только определенные данные (класс, функцию), то необходимо присвоитьmodule.exportsэти данные.
Например, мы описали класс User
.
При передаче module.exports.User = User
в результате импорта const User = required('./user')
переменнаяUser
будет содержать свойство User.User
, которое и отвечает за этот класс.
Но если мы переприсвоем module.exports
следующим образом module.exports = User
, то переменная User
при импорте будет являться классом. То есть мы сможем создавать экземпляры класса с помощью new User()
, а не как в предыдущем случае с помощью new User.User()
.
При этом мы не можем присвоить класс User
в переменную exports
, т.е записать exports = User
, потому что переменная exports
является ссылкой на module.exports
, а после переприсвоения перестанет на него ссылаться.
Практическое задание
Используя ES6 cоздать класс Person в файле person.js, конструктор которого принимает имя и возраст в качестве аргумента. Все экземпляры этого класса должны иметь общий метод show , который выводит информацию о пользователя.
В файл index.js создать экземпрляр класса Person и вывести на консоль информацию о пользователе.
Глоссарий
Термин | Значение |
---|---|
Экспорт | Предоставление программным модулем некоторой части описанных в нём типов, констант, переменных, классов, процедур или функций в пользование другим модулям, входящим в состав той же программы. |
Импорт | Добавление данных, вставка данных из внешних источников в текущий файл/документ/базу данных. |
Подключение модуля | Импорт модуля в файл |
Ссылки
- ES6 Classes[Электронный ресурс]. – https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes