Создание модуля Node.js

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

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

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

Требования

  • Установка Node.js и npm. В данном мануале используется версия 10.17.0. Чтобы установить ее на macOS, читайте этот мануал. Чтобы установить ее на Ubuntu 18.04 через PPA, выполните этот мануал. Вместе с Node.js устанавливается и npm (в данном мануале используется версия 6.11.3).
  • Базовые навыки работы с файлом package.json и командами npm.
  • Навыки работы с Node.js REPL. Больше информации по этому вопросу вы найдете здесь.

1: Создание модуля

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

Сначала нужно решить, какие данные о цветах мы будем хранить в своем модуле. Каждый цвет будет объектом, который содержит свойство name (по нему люди могут легко его идентифицировать) и code (это строка, содержащая цветовой код HTML). Цветовые коды HTML представляют собой шестизначные шестнадцатеричные числа, которые позволяют изменять цвет элементов на веб-странице. Узнать больше о цветовых кодах HTML можно здесь.

Затем нужно решить, какие цвета вы хотите поддерживать в своем модуле. Модуль будет содержать массив по имени allColors, который будет содержать шесть цветов. Также модуль будет включать функцию getRandomColor(), которая будет случайным образом выбирать цвет из массива и выводить его на экран.

В терминале создайте новую папку colors и перейдите в нее:

mkdir colors
cd colors

Инициализируйте npm, чтобы позже другие программы могли импортировать этот модуль:

npm init -y

Флаг -y пропустит запросы по настройке вашего package.json. Если бы мы собирались опубликовать этот модуль в npm, нам нужно было бы ответить на все эти запросы соответствующими данными.

В этом случае вы получите такой вывод:

{
"name": "colors",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

Теперь откройте текстовый редактор (например nano) и создайте новый файл, который будет служить точкой входа для модуля:

nano index.js

Этот модуль будет делать несколько вещей. Сначала мы определим класс Color, который будет содержать название цвета и его код. Добавьте следующие строки для создания этого класса:

class Color {
constructor(name, code) {
this.name = name;
this.code = code;
}
}

Теперь, когда у вас есть структура данных для класса Color, добавьте в ваш модуль несколько экземпляров. Добавьте следующий выделенный массив в файл:

class Color {
constructor(name, code) {
this.name = name;
this.code = code;
}
}
const allColors = [
new Color('brightred', '#E74C3C'),
new Color('soothingpurple', '#9B59B6'),
new Color('skyblue', '#5DADE2'),
new Color('leafygreen', '#48C9B0'),
new Color('sunkissedyellow', '#F4D03F'),
new Color('groovygray', '#D7DBDD'),
];

Затем добавьте функцию, которая случайным образом выбирает элемент из только что созданного массива allColors:

class Color {
constructor(name, code) {
this.name = name;
this.code = code;
}
}
const allColors = [
new Color('brightred', '#E74C3C'),
new Color('soothingpurple', '#9B59B6'),
new Color('skyblue', '#5DADE2'),
new Color('leafygreen', '#48C9B0'),
new Color('sunkissedyellow', '#F4D03F'),
new Color('groovygray', '#D7DBDD'),
];
exports.getRandomColor = () => {
return allColors[Math.floor(Math.random() * allColors.length)];
}
exports.allColors = allColors;

Ключевое слово exports ссылается на глобальный объект, доступный в каждом модуле Node.js. Все функции и объекты, хранящиеся в объекте exports, открываются, когда другие модули Node.js импортируют его. Например, функция getRandomColor() была создана непосредственно в объекте exports. Затем мы добавили в объект exports свойство allColors, которое ссылается на локальной массив allColors, созданный ранее в скрипте.

Когда другие модули импортируют этот модуль, allColors и getRandomColor() будут доступны для использования.

Сохраните и закройте файл.

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

2: Тестирование приложения с помощью REPL

Прежде чем создавать полное приложение, лучше уделить немного времени тестированию и убедиться, что модуль работает. На этом этапе мы используем REPL для загрузки модуля colors. Находясь в REPL, мы вызовем функцию getRandomColor(), чтобы увидеть, ведет ли она себя так, как мы ожидаем.

Запустите REPL Node.js в той папке, в которой находится файл index.js:

node

Когда REPL запустится, вы увидите командную строку, которая начинается с символа >. Это означает, что вы можете ввести код JavaScript, который будет сразу же оценен.

Читайте также: Использование интерактивной оболочки REPL в Node.js

Сначала введите следующую строку:

colors = require('./index');

В этой команде require() загружает модуль colors в его точку входа. Когда вы нажмете ENTER, вы получите:

{
getRandomColor: [Function],
allColors: [
Color { name: 'brightred', code: '#E74C3C' },
Color { name: 'soothingpurple', code: '#9B59B6' },
Color { name: 'skyblue', code: '#5DADE2' },
Color { name: 'leafygreen', code: '#48C9B0' },
Color { name: 'sunkissedyellow', code: '#F4D03F' },
Color { name: 'groovygray', code: '#D7DBDD' }
] }

REPL показывает значение colors, которое представляет все функции и объекты, импортированные из файла index.js. Когда вы используете ключевое слово require, Node.js возвращает все содержимое объекта exports данного модуля.

Напомним, что вы добавили getRandomColor() и allColors в exports  в модуле colors. По этой причине вы видите их в REPL, когда они импортируются.

Теперь в командной строке протестируйте функцию getRandomColor():

colors.getRandomColor();

Вы получите случайный цвет:

Color { name: 'groovygray', code: '#D7DBDD' }

Поскольку индекс выбирается случайно, вывод может отличаться. Теперь, когда вы подтвердили, что модуль colors работает, выйдите из REPL Node.js:

.exit

Это вернет вас в командную строку терминала.

Используя REPL, вы только что подтвердили, что модуль работает должным образом. Давайте теперь загрузим свой модуль в приложение, как в реальном проекте.

3: Сохранение локального модуля как зависимости

При тестировании модуля в REPL вы импортировали его с относительным путем: то есть вы использовали расположение файла index.js относительно рабочего каталога, чтобы получить его содержимое. Этот метод работает, но обычно в программировании лучше импортировать модули по их именам, чтобы при изменении контекста импорт работал. На этом этапе мы установим модуль colors с помощью функции install.

Установите новый модуль Node.js вне папки colors. Сначала перейдите в предыдущий каталог и создайте новую папку:

cd ..
mkdir really-large-application

Перейдите в каталог нового проекта:

cd really-large-application

Как и в случае с модулем colors, инициализируйте папку с помощью npm:

npm init -y

Данный package.json сгенерирует:

{
"name": "really-large-application",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

Теперь установите модуль colors и используйте флаг –save, чтобы он был записан в файл package.json:

npm install --save ../colors

Вы только что установили свой модуль colors в новом проекте. Откройте файл package.json, чтобы увидеть новую локальную зависимость:

nano package.json

Вы обнаружите, что в него были добавлены следующие выделенные строки:

{
"name": "really-large-application",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"colors": "file:../colors"
}
}

Закройте файл.

Модуль colors был скопирован в каталог node_modules. Проверьте это с помощью следующей команды:

ls node_modules

Она вернет следующий вывод:

colors

Используйте установленный локальный модуль в этой новой программе. Снова откройте текстовый редактор и создайте еще один файл JavaScript:

nano index.js

Ваша программа сначала импортирует модуль colors. Затем она произвольно выберет цвет, используя предоставленную модулем функцию getRandomColor(). Наконец, она выведет на консоль сообщение о том, какой цвет использовать.

Введите следующий код в index.js:

const colors = require('colors');
const chosenColor = colors.getRandomColor();
console.log(`You should use ${chosenColor.name} on your website. It's HTML code is ${chosenColor.code}`);

Сохраните и закройте файл.

Ваше приложение теперь может сообщать пользователю случайный цвет для веб-сайта.

Запустите этот скрипт:

node index.js

Ваш вывод будет примерно таким:

You should use leafygreen on your website. It's HTML code is #48C9B0

Итак, вы успешно установили модуль colors и можете управлять им, как и любым другим пакетом npm, используемым в вашем проекте. Однако, если вы добавите больше цветов и функций в свой локальный модуль colors, вам придется запустить в своих приложениях команду npm update, чтобы иметь возможность использовать новые параметры. Далее мы попробуем настроить автоматические обновления при изменении кода модуля.

4: Связывание с локальным модулем

Если ваш локальный модуль находится в активной разработке, постоянно обновлять пакеты вручную может быть утомительно. Но вы можете связать модули. Связывание модулей гарантирует, что все обновления в локальном модуле немедленно отразятся в приложениях, использующих его.

На этом этапе мы свяжем модуль colors с вашим приложением. Мы также изменим модуль colors и проверим, появились ли его последние изменения в приложении (без переустановки или обновления вручную).

Сначала удалите локальный модуль:

npm un colors

npm связывает модули с помощью символических ссылок (или симлинков): это ссылки, которые указывают на файлы или каталоги на вашем компьютере. Связывание модуля выполняется в два этапа:

  1. Создание глобальной ссылки на модуль. npm создает симлинк между глобальным каталогом node_modules и каталогом модуля. Глобальный каталог node_modules – это каталог, в котором установлены все общесистемные пакеты npm (каждый пакет, который вы устанавливали с флагом -g).
  2. Создание локальной ссылки. npm создает симлинк между локальным проектом, использующим модуль, и глобальной ссылкой модуля.

Сначала создайте глобальную ссылку, вернувшись в каталог colors и используя команду link:

cd ../colors
sudo npm link

После этого оболочка вернет:

/usr/local/lib/node_modules/colors -> /home/8host/colors

В каталоге node_modules вы создали симлинк на каталог colors.

Вернитесь в каталог really-large-application и создайте ссылку на пакет:

cd ../really-large-application
sudo npm link colors

Вы получите подобный вывод:

/home/8host/really-large-application/node_modules/colors -> /usr/local/lib/node_modules/colors -> /home/8host/colors

Примечание: Вместо link можно использовать ln. Например, команда npm ln colors будет работать точно таким же образом.

Как показывают выходные данные, вы только что создали символическую ссылку из локального каталога node_modules приложения на глобальную ссылку, которая указывает на фактический каталог с модулем colors.

Процесс связывания завершен. Запустите файл, чтобы убедиться, что он работает:

node index.js
You should use sunkissedyellow on your website. It's HTML code is #F4D03F

Функциональность вашей программы не повреждена. Затем убедитесь, что обновления применяются сразу же. В текстовом редакторе снова откройте файл index.js:

cd ../colors
nano index.js

Теперь добавьте функцию, которая выбирает лучший из существующих оттенков синего. Она не принимает аргументов и всегда возвращает третий элемент массива allColors. Добавьте эти строки в конец файла:

class Color {
constructor(name, code) {
this.name = name;
this.code = code;
}
}
const allColors = [
new Color('brightred', '#E74C3C'),
new Color('soothingpurple', '#9B59B6'),
new Color('skyblue', '#5DADE2'),
new Color('leafygreen', '#48C9B0'),
new Color('sunkissedyellow', '#F4D03F'),
new Color('groovygray', '#D7DBDD'),
];
exports.getRandomColor = () => {
return allColors[Math.floor(Math.random() * allColors.length)];
}
exports.allColors = allColors;
exports.getBlue = () => {
return allColors[2];
}

Сохраните и закройте файл. Откройте файл index.js в каталоге really-large-application:

cd ../really-large-application
nano index.js

Отправьте вызов недавно созданной функции getBlue() и выведите предложение со свойствами цвета. Добавьте эти строки в конец файла:

const colors = require('colors');
const chosenColor = colors.getRandomColor();
console.log(`You should use ${chosenColor.name} on your website. It's HTML code is ${chosenColor.code}`);
const favoriteColor = colors.getBlue();
console.log(`My favorite color is ${favoriteColor.name}/${favoriteColor.code}, btw`);

Сохраните и закройте файл.

Теперь код использует новую функцию getBlue(). Выполните файл:

node index.js

Вы получите такой вывод:

You should use brightred on your website. It's HTML code is #E74C3C
My favorite color is skyblue/#5DADE2, btw

Ваш скрипт смог использовать новую функцию в модуле colors без команды npm update. Это облегчит внесение изменений в это приложение в процессе разработки.

При написании больших и сложных приложений подумайте о том, как связанный код можно сгруппировать в модули и как вы хотите эти модули настроить. Если ваш модуль будет использоваться только одной программой, он может оставаться в том же проекте и работать по относительному пути. Если же вы собираетесь переместить его из каталога этого проекта в другое место, лучше использовать установку или связывание. Модули в активной разработке также выигрывают от автоматических обновлений ссылок. Если модуль не находится в активной разработке, использование npm install может быть более простым вариантом.

Читайте также: Подготовка приложения Node.js к производству в Ubuntu 18.04

Tags: , , ,

Добавить комментарий