Автор выбрал фонд Open Internet/Free Speech для получения пожертвования в рамках программы Write for DOnations.
В Node.js модуль — это набор функций и объектов JavaScript, который могут использовать внешние приложения. Описание части кода как модуля относится не столько к самому коду, сколько к тому, что он делает. Любой файл или набор файлов Node.js можно считать модулем, если его функции и данные готовы для использования внешними программами.
Поскольку модули обеспечивают функции, которые можно использовать в более масштабных программах, они позволяют создавать слабо связанные приложения, масштабируемые по мере роста сложности. Так модули открывают возможность предоставлять свой код другим разработчикам. Написание модулей для экспорта полезных функций и данных позволит вам стать участником широкого сообщества разработчиков Node.js. Все пакеты, используемые вами на npm, были составлены и опубликованы как модули. Таким образом, создание модулей можно назвать обязательным умением для разработчика Node.js.
В этом обучающем руководстве мы создадим модуль Node.js, предлагающий веб-разработчикам цвета для использования в дизайне. Мы сохраним цвета в массиве и предоставим функцию случайного подбора цвета. После этого мы рассмотрим различные способы импорта модулей в приложение Node.js.
package.json
, опыт с командами npm также будет полезен. Чтобы приобрести этот опыт, выполните обучающее руководство Использование модулей Node.js с npm и package.json, в особенности раздел Шаг 1 — Создание файла package.json
.На этом шаге вы создадите свой первый модуль Node.js. Ваш модуль будет содержать массив с набором цветов и предоставлять функцию случайного выбора цвета. Мы используем встроенное свойство Node.js exports
, чтобы сделать функцию и массив доступными для внешних программ.
Для начала мы определим, какие данные о цветах будут храниться в вашем модуле. Каждый цвет будет представлять собой объект со свойством name
, которое люди смогут легко распознать, и со свойством code
, представляющим собой строку с цветовым кодом HTML. Цветовые коды HTML представляют собой шестизначные числа в шестнадцатеричном формате, позволяющие изменять цвет элементов веб-страницы. Дополнительную информацию о цветовых кодах HTML можно узнать в статье Цветовые коды и наименования в HTML.
Затем вы сможете решить, какие цвета должен поддерживать ваш модуль. Наш модуль будет содержать массив allColors
, содержащий шесть цветов. Также ваш модуль будет содержать функцию getRandomColor()
, которая будет случайным образом выбирать из массива цвет и возвращать его.
Откройте терминал, создайте новую папку colors
и перейдите в нее:
- mkdir colors
- cd colors
Инициализируйте npm, чтобы другие программы могли импортировать этот модуль на последующих шагах этого обучающего руководства:
- npm init -y
Мы используем флаг -y
, чтобы пропустить обычные диалоги настройки файла package.json
. Если бы вы публиковали этот модуль в npm, вы бы ввели в этих диалогах соответствующие данные, как объясняется в статье Использование модулей Node.js с npm и package.json.
В данном случае вывод будет выглядеть так:
Output{
"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
. Экземпляр класса Color
будет создаваться с именем и кодом HTML. Добавьте следующие строки для создания класса:
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
. Затем мы добавили свойство allColors
в объекте exports
. Это свойство ссылается на локальный постоянный массив allColors
, созданный на предыдущих шагах сценария.
При импорте этого модуля другими модулями allColors
и getRandomColor()
открываются и становятся доступными для использования.
Сохраните и закройте файл.
Мы создали модуль, содержащий массив цветов и функцию, возвращающую случайный цвет. Мы также экспортировали массив и функцию, чтобы внешние программы могли их использовать. На следующем шаге мы используем наш модуль в других приложениях, чтобы продемонстрировать эффекты экспорта
.
Прежде чем создать полное приложение, нужно убедиться, что наш модуль работает. На этом шаге мы используем REPL для загрузки модуля colors
. В REPL вы вызовете функцию getRandomColor()
и убедитесь, что она ведет себя ожидаемым образом.
Запустите Node.js REPL в той же папке, что и файл index.js
:
- node
После запуска REPL вы увидите командную строку >
. Это означает, что вы можете ввести код JavaScript, который немедленно пройдет оценку. Если вы хотите узнать больше об этом, следуйте нашим указаниям по использованию REPL.
Вначале введите следующее:
- colors = require('./index');
В этой команде require()
загружает модуль colors
в точке входа. При нажатии ENTER
вы получите следующее:
Output{
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();
Будет выведен случайный цвет:
OutputColor { name: 'groovygray', code: '#D7DBDD' }
Поскольку индекс случайный, вывод может отличаться. Мы убедились в работе модуля colors
и теперь можем выйти из Node.js REPL:
- .exit
Эта команда вернет вас в командную строку терминала.
Мы только что использовали REPL для проверки работы нашего модуля. Теперь мы применим те же самые концепции и загрузим модуль в приложение, как при работе с реальным проектом.
При тестировании модуля REPL мы использовали для его импорта относительный путь. Это означает, что мы использовали расположение файла index.js
по отношению к рабочей директории для получения ее содержимого. Хотя такой подход работает, с точки зрения программирования лучше импортировать модули по именам, чтобы импортированные модули не перестали работать при изменении контекста. На этом шаге мы установим модуль colors
с помощью функции install
локального модуля npm.
Установите новый модуль Node.js вне папки colors
. Вначале вернитесь в предыдущую директорию и содайте новую папку:
- cd ..
- mkdir really-large-application
Теперь переходите к новому проекту:
- cd really-large-application
Как и в случае с модулем colors
, инициализируйте папку с помощью npm:
- npm init -y
Будет сгенерирован следующий файл package.json
:
Output{
"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
Результат будет выглядеть следующим образом:
Outputcolors
Используйте в новой программе установленный локальный модуль. Заново откройте текстовый редактор и создайте еще один файл 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
Вывод будет выглядеть следующим образом:
OutputYou should use leafygreen on your website. It's HTML code is #48C9B0
Вы успешно установили модуль colors
и теперь можете управлять им, как и любым другим пакетом npm, используемым в вашем проекте. Если вы добавите дополнительные цвета и функции в локальный модуль colors
, вам нужно будет запустить в приложениях команду npm update
для использования новых возможностей. На следующем шаге мы используем локальный модуль colors
по-другому и получим автоматические обновления при изменении кода модуля.
Если локальный модуль находится в разработке, постоянное обновление пакетов может оказаться непростой задачей. В качестве альтернативы можно выполнить привязку модулей. При привязке модуля все обновления этого модуля немедленно отражаются в использующих его приложениях.
На этом шаге мы привяжем модуль colors
к нашему приложению. Также мы изменим модуль colors
и подтвердим, что его последние изменения будут работать в приложении без переустановки или обновления.
Вначале следует удалить локальный модуль:
- npm un colors
npm привязывает модули, используя символические ссылки (symlink), представляющие собой указатели на файлы или директории вашего компьютера. Привязка модуля выполняется в два этапа:
node_modules
и директорией вашего модуля. В глобальной директории node_modules
устанавливаются все системные пакеты npm (любые пакеты, устанавливаемые с флагом -g
).Вначале нужно создать глобальную ссылку, вернувшись в папкуcolors
и используя команду link
:
- cd ../colors
- sudo npm link
После этого в оболочке появится следующее:
Output/usr/local/lib/node_modules/colors -> /home/sammy/colors
Вы только что создали связь symlink между папкой node_modules
и директорией colors
.
Теперь вернитесь в папку really-large-application
и выполните привязку пакета:
- cd ../really-large-application
- sudo npm link colors
Вы получите примерно следующий результат:
Output/home/sammy/really-large-application/node_modules/colors -> /usr/local/lib/node_modules/colors -> /home/sammy/colors
Примечание. Если вам нравится сокращать, вы можете использовать синтаксис ln
вместо link
. Например, команда npm ln colors
будет работать точно так же.
Как показывает вывод, вы только что создали связь symlink между локальной директорией node_modules
приложения really-large-application
и связью symlink директории colors
в глобальной node_modules
, которая указывает на фактическую директорию в модуле colors
.
Процесс привязки завершен. Запустите файл, чтобы проверить его работу:
- node index.js
Вывод будет выглядеть следующим образом:
OutputYou should use sunkissedyellow on your website. It's HTML code is #F4D03F
Функционал вашей программы не пострадал. Протестируйте обновления и убедитесь, что они применяются немедленно. Заново откройте в текстовом редакторе файл index.js
в модуле colors
:
- 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
Вы увидите примерно следующее:
OutputYou 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 представляет собой файл JavaScript с функциями и объектами, которые могут использоваться другими программами. Также мы создали модуль и прикрепили свои функции и объекты к глобальному объекту exports
, чтобы сделать их доступными для внешних программ. В заключение мы импортировали модуль в программу и показали, как можно сочетать модули в больших приложениях.
Теперь вы знаете, как создавать модули. Подумайте о том, какую программу вы хотите написать, и разбейте ее на компоненты, сохраняя уникальные наборы действий и данных в собственных модулях. Чем больше вы будете тренироваться в написании модулей, тем быстрее вы научитесь писать качественные программы Node.js. Еще один пример приложения Node.js, использующего модули, можно найти в обучающем руководстве Настройка приложения Node.js для работы в производственной среде в Ubuntu 18.04.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!