5. Модули для Node.JS

Всем привет, на этом занятии мы создадим наш первый проект на Node.JS. Нашей основной целью при создании этого проекта будет знакомство с модулями, способами которые Node.JS предлагает для организации проекта. И начнем мы с того, что откроем WebStorm или ваш любимый редактор в новой пустой директории «start». В этой директории будет находится проект Node.JS. Так как я использую WebStorm, то мне так же понадобится небольшая инициализация. Запускаем WebStorm > File > Settings… > (в левой колонке) Languages & Frameworks > Node.js and NPM  > ( в правой части окна) Coding Assistance > Node.js Core library is not enabled > Жмем кнопку «Enable».

Screenshot_5_1

По умолчанию WebStorm считает, что я редактирую обычный html, обычный браузерный JS и он мне будет предлагать варианты автодополнения соответствующие браузерному скрипту, а мне нужны именно Node.JS. По этому я жму кнопку «Usage scope», которая появилась на месте «Enable». В появившемся окошке выделяем строку с названием проекта и кликаем по списку подключенных библиотек, он(список) находится на пересечении строки названия проекта и столбца с названием «Library»

Screenshot_5_2

Теперь в выпавшем списке кликаем по Clear, так мы очистили список подключенных библиотек, теперь можем добавлять нужные нам библиотеки отметив их галочками, со всеми ними мы в дальнейшем познакомимся.  К стати сейчас мы редактируем список библиотек на уровне проекта, но можем и на уровне отдельной папки кликнув на пересечении названия этой папки и столбца «Library» и выбрав библиотеки из списка. Screenshot_5_3

И так, мы добавили библиотеку «Node.JS Core» для всего проекта. Инициализация завершена.

Создаем первый файл, этот файл будет называться «server.js». Для этого правой кнопкой мыши кликаем по названию проекта,

Screenshot_5_4в выпадающем окне наводим на New далее кликаем по File. В появившемся окошке вводим название будущего файла с разрешением «server.js».

 

 

Целью этого занятия является знакомство с модулями, по этому я буду писать простой JavaScript.

Я добавлю в этот файл объект «User», который будет создавать пользователей. У пользователей могут быть конечно же методы например «hello» где «(who)» это другой User. Далее создаем двух пользователей и запускаем наш код вызвав метод «hello» у одного из пользователей и передав ему другого пользователя в качестве аргумента.

Вспоминаем, мы уже рассматривали как открыть окно команд в нужной нам папке. Открываем его в папке с проектом и водим следующую команду: C:\start>node server.js

Screenshot_5_5

Отлично работает, начало положено. Теперь представим себе, что мы развиваем наш проект дальше. «User», это достаточно мощный объект и там может быть много всего и функции растут. Со временем появляется необходимость вынести этот «User» в отдельный файл. И тут-то в дело вступают модули.

Подключение: require

В браузере, когда мы хотим добавить еще один скрипт на страницу мы используем, как правило тег: <script></script>. В Node.JS для этой же цели мы используем специальную команду: «require» и работает она совсем, совсем по другому. Давайте рассмотрим это на нашем примере.
Для псевдокласса «User» я создам отдельный файл. И перемещу User’а из «server.js» в «user.js». Для того, чтоб нам было удобно, я даже расположу его в отдельной колонке.

Screenshot_5_6

Для того, чтобы из одного файла подключить другой, используется команда:

можно указать расширение «.js», можно не указывать. И чтобы проконтролировать выполнение этой команды, я добавлю в «user.js»:

что ж, запускаем:

Screenshot_5_7

Похоже, что то не так, произошла ошибка! Node.JS не находит здесь переменную User, она не определена.

Screenshot_5_8

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

Переменная «exports»

Но как же быть в данном случае? Ведь здесь то я как раз хочу, чтоб переменная «User» была доступна в «server.js». Для этого, как правило, используется система экспортов. В каждом модуле есть специальная переменная «exports». Это объект и то, что я туда положу, вернется как результат «require(./someFile.js)». Например, в данном случае:

Screenshot_5_9

Таким образом каждый модуль может объявить свои собственные приватные функции, переменные и то, что он хочет отдать наружу, вот таким образом экспортировать.

Переменная «global»

Может возникнуть резонный вопрос, а что если мы хотим все таки глобальные переменные? Например есть такие объекты как скажем «logger» или «База данных» или какой то глобальный объект приложения, которые мы хотим, чтобы были доступны явно и везде. Без всяких там экспортов, просто потому что они, такие вот важные. На самом деле в Node.JS есть концепция глобальных переменных, но вместо объекта «window», который используется в браузере, используется объект «global».  И то, что мы пишем в этот объект «global», именно то, что записываем явным образом, вот так:

становится глобальной переменной. И если я так написал, то поубирав все лишнее из наших файлов, могу попробовать запустить еще раз.

Screenshot_5_10

О! Работает. Сначала подключился файл «require(./user);», он обработался, «global.User = User;» сработал и  «var = vasya» и «var = petya», у меня глобальные переменные. То есть технически это возможно, однако в Node.JS есть ряд особенностей этой системы модулей, которые мы скоро с вами изучим, которые позволяют обойтись совершенно без глобальных переменных и на практике, этот объект «global» практически не используется. И далее мы будем чувствовать себя комфортно без всяких глобальных переменных.

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

Виды модулей: JS, NODE, JSON

То, что мы с вами рассмотрели — тип модуля «JS» (мы ведь подключали «user.js «), это самый часто используемый модуль JavaScript файл. Но есть и другие. Следующий тип  модуля, вы вряд ли сейчас захотите использовать. Этот тип модуля носит расширение «.node» и делается он путем компиляции файла на языке «C++». Как правило, такое делают в тех случаях, когда нужно либо очень хорошая производительность, либо нужно использовать какие то возможности операционной системы, к которым, почему то нельзя, сейчас, обратиться из JavaScrip из Node.JS. И наконец третий тип модуля, это «JSON».

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

в отдельный файл, который будет хранить соответствия английских фраз и фраз на соответствующем языке.

Создаем новый файл с названием «ru.json». Этот файл будет хранить соответствия, например:

Именно формат Json нужен, то есть если бы я записал вот так:

Это было бы не правильно. Формат Json требует обязательного указания кавычек, это не JavaScript объект, это формат.
И теперь в user.js я просто пишу:

Могу указать расширение, могу не указывать. Если Node.JS не находит файл «ru.js» он ищет файл «ru.json». Загружает его, интерпретирует и получившийся объект будет хранить в «var phrases». Что ж проверим:

Screenshot_5_11

Отлично, все еще работает!
Модули в формате «.json» используйте в тех случаях когда хочется хранить какие-то данные в простейшем виде, в виде файлов.

Модуль-директория DIR/index

Теперь мы будем дальше развивать проект и вместе с файлом «user.js» нам для реализации функционала «Юзера» понадобятся еще  какие-то файлы. При этом будет целесообразно выделить модуль в отдельную директорию. Создадим директорию с именем «user».

Screenshot_5_12

Screenshot_5_13

Screenshot_5_14

Директории тоже можно подключать. При этом Node.JS сначала ищет файл с таким названием «user.js» потом «user.json» если он не находит ни того ни того, он ищет директорию с названием «user». И в этой директории хочет взять файл «index.соответствующее расширение», считает его модулем. Соответственно я «user.js» перетаскиваю в директорию «user»(в WebStorm перемещение файла из директории в директорию можно совершить простым перетаскиванием, зажав левую кнопку мыши) и называю его «index.js».  К нему же и положу наш «ru.json». Для того, чтоб переименовать файл «user.js», после его перемещения, надо кликнуть левой кнопкой мыши по файлу, в выпадающем меню выбрать пункт «Refactor» и выбрать «rename». В появившемся окне изменяем название файла на «index.js». Проверяем — Все работает.  Теперь, если мне понадобятся дополнительные файлы для реализации функционала «Юзера», то я смогу добавить их в эту директорию.

Далее приведу наш рабочий код:

Итак мы с вами знаем:

  • Что такое модуль, фактически это файл, который подключается при помощи «require( )».
  • Мы знаем какие виды переменных есть в модуле: exports и global
  • Какие виды модулей существуют: JS, NODE, JSON
  • Так же мы знаем, как организовать модуль в виде директории

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

One thought on “5. Модули для Node.JS”

  1. Константин, благодарю за урок!
    Случайно наткнулся на ваш блог и очень рад этому. Все обьясняете доступно и легко.

Обсуждение закрыто.