Работа с модулями в 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

  1. If X is a core module,

    a. return the core module

    b. STOP

  2. If X begins with '/'

    a. set Y to be the filesystem root

  3. If X begins with './' or '/' or '../'

    a. LOAD_AS_FILE(Y + X)

    b. LOAD_AS_DIRECTORY(Y + X)

  4. LOAD_NODE_MODULES(X, dirname(Y))

  5. THROW "not found"

LOAD_AS_FILE(X)

  1. If X is a file, load X as JavaScript text. STOP

  2. If X.js is a file, load X.js as JavaScript text. STOP

  3. If X.json is a file, parse X.json to a JavaScript Object. STOP

  4. If X.node is a file, load X.node as binary addon. STOP

LOAD_INDEX(X)

  1. If X/index.js is a file, load X/index.js as JavaScript text. STOP

  2. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP

  3. If X/index.node is a file, load X/index.node as binary addon. STOP

LOAD_AS_DIRECTORY(X)

  1. 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)

  2. LOAD_INDEX(X)

LOAD_NODE_MODULES(X, START)

  1. let DIRS=NODE_MODULES_PATHS(START)

  2. for each DIR in DIRS:

    a. LOAD_AS_FILE(DIR/X)

    b. LOAD_AS_DIRECTORY(DIR/X)

NODE_MODULES_PATHS(START)

  1. let PARTS = path split(START)

  2. let I = count of PARTS - 1

  3. let DIRS = []

  4. 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

  5. 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 и вывести на консоль информацию о пользователе.

Глоссарий

Термин Значение
Экспорт Предоставление программным модулем некоторой части описанных в нём типов, констант, переменных, классов, процедур или функций в пользование другим модулям, входящим в состав той же программы.
Импорт Добавление данных, вставка данных из внешних источников в текущий файл/документ/базу данных.
Подключение модуля Импорт модуля в файл

Ссылки

  1. ES6 Classes[Электронный ресурс]. – https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes

results matching ""

    No results matching ""