Автор выбрал фонд Open Internet/Free Speech для получения пожертвования в рамках программы Write for DOnations.

Введение

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

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

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

Предварительные требования

  • Необходимо, чтобы в вашей среде разработки были установлены Node.js и npm. В этом обучающем руководстве используется версия 10.17.0. Чтобы установить его в macOS или Ubuntu 18.04, следуйте указаниям руководства Установка Node.js и создание локальной среды разработки в macOS или раздела Установка с помощью PPA руководства Установка Node.js в Ubuntu 18.04. При установке Node.js также выполняется установка npm, в этом обучающем руководстве используется версия 6.11.3.
  • Вы должны быть знакомы с файлом package.json, опыт с командами npm также будет полезен. Чтобы приобрести этот опыт, выполните обучающее руководство Использование модулей Node.js с npm и package.json, в особенности раздел Шаг 1 — Создание файла package.json.
  • Также будет полезно познакомиться со структурой Node.js REPL (чтение-оценка-печать-цикл). Мы используем это для тестирования нашего модуля. Если вам требуется дополнительная информация, обратитесь к руководству Использование REPL в Node.js.

Шаг 1 — Создание модуля

На этом шаге вы создадите свой первый модуль 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. Добавьте следующие строки для создания класса:

~/colors/index.js
class Color {
  constructor(name, code) {
    this.name = name;
    this.code = code;
  }
}

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

~/colors/index.js
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:

~/colors/index.js
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() открываются и становятся доступными для использования.

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

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

Шаг 2 — Тестирование модуля с REPL

Прежде чем создать полное приложение, нужно убедиться, что наш модуль работает. На этом шаге мы используем 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();

Будет выведен случайный цвет:

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

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

  • .exit

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

Мы только что использовали REPL для проверки работы нашего модуля. Теперь мы применим те же самые концепции и загрузим модуль в приложение, как при работе с реальным проектом.

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

При тестировании модуля 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

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

~/really-large-application/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

Результат будет выглядеть следующим образом:

Output
colors

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

  • nano index.js

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

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

~/really-large-application/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

Вывод будет выглядеть следующим образом:

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

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

Шаг 4 — Привязка локального модуля

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

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

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

  • npm un colors

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

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

Вначале нужно создать глобальную ссылку, вернувшись в папку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

Вывод будет выглядеть следующим образом:

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

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

  • cd ../colors
  • nano index.js

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

~/colors/index.js
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() и распечатайте предложение со свойствами цвета. Добавьте эти выражения в конец файла:

~/really-large-application/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}`);

const favoriteColor = colors.getBlue();
console.log(`My favorite color is ${favoriteColor.name}/${favoriteColor.code}, btw`);

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

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

  • node index.js

Вы увидите примерно следующее:

Output
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 представляет собой файл JavaScript с функциями и объектами, которые могут использоваться другими программами. Также мы создали модуль и прикрепили свои функции и объекты к глобальному объекту exports, чтобы сделать их доступными для внешних программ. В заключение мы импортировали модуль в программу и показали, как можно сочетать модули в больших приложениях.

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

0 Comments

Creative Commons License