Открыть меню    

nodejs основы

NODE.JS – программное средство для выполнения js.

Nodejs = V8 + I/O + библиотеки

V8: быстро, современно, экономно

Преимущества

  • Javascript
  • Общий код на клиенте и на сервере
  • Основные задачи по web
  • Много соединений и задач одновременно
  • Легко создать рабочий прототип
  • Удобный менеджер пакетов npm
  • Сообщество

Установка

nodejs.org

при установке nodejs прописывает себя в переменную PATH (+ npm), [администрирование – переменные среды]; можно проверить в командной строке:
set PATH

Как правило под nodejs запускают файлы: напишем простой скрипт и запустим его посредством командной строки:

Скрипт будет выполнен и результат отобразится в командной строке.

Документация по nodejs

Node.js v0.12.2 Manual & Documentation (API)

Модули nodejs

Чтобы разобраться как работают встроенные модули nodejs необходимо скачать архив с исходниками с сайта nodejs (source code). И зайти в директорию lib. (команда dir - получаем список файлов через командную строку; Если вам необходимо перечислить файлы во всех вложенных папках, то вместо "dir" используйте "dir /s"). Если вы поставили nodejs из пакета, то в папке lib файлов не обнаружите.

В nodejs есть модули с разной степенью стабильности. (например, 0 – не стоит использовать; 1,2 – использовать можно но API модуля может измениться).

Функции растут (проект развивается) и со временем нам потребуется вынести функцию-конструктор USER в отдельный файл. Вот тут-то в дело вступают модули.

Модули этого своего рода способ, который предлагает nodejs для организации проекта.

Проекты как правило разрастаются, что приводит к желанию разбить проект на несколько файлов – вот тут-то в дело вступают модули.

require

Для html-страниц для подключения скриптов используют тег script. В nodejs существует специальная команда require.

var user = require('./user');

В нашем примере мы обращаемся к файлу (user.js) в той же директории (расширение (.js) писать необязательно).

//require("./user"); // .js указывать необязательно
// в этом случае файл будет выполнен, но переменной USER
// не будет
// в этом главное отличие от тегов script от nodejs
// В node.js функции и переменные каждого  модуля являются глобальными
// для данного файла (самого модуля) и они не становятся автоматически
// доступными при подключении (require("./user"))
// Но как же получить доступ?
// В каждом модуле есть специальная переменная exports - это объект и то
// что я туда положу вернется как результат require
var user = require("./user.js");
// результат: user = { User: function }

Первое отличие модульной системы nodejs от браузерных скриптов: если в браузере есть два тега script, то функция, которая определена на глобальном уровне одном из них доступна и в другом, а в nodejs нет. В nodejs функции и переменные являются глобальными для данного файла (они не становятся доступными при подключении посредством require). Таким образом nodejs позволяет писать действительно независимые модули. Но чтобы модуль был доступен используется система экспортов. В каждом модуле есть специальная переменная exports.

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

Подключаем непосредственно папку var user = require("./user");, в которой лежит соответствующий index.js.

Например

./user/index.js

function User(name){
    this.name = name;
}

User.prototype.hello = function(who){
    console.log(phrases.Hello + ", " + who.name);
};

exports.User = User;

Подключаем и используем конструктор User в файле ./server.js

//server.js

var user = require('./user');

var vasya = new user.User("Вася");

«./» - относительно текущей папки

exports – это объект и то, что туда положено, вернется как результат require (exports.jpg). Таким образом модуль может объявить свои приватные переменные/функции и экспортировать лишь то, что необходимо.

Для глобальных переменных и т.д. существует объект global

global.User = User;

Итог

  • Подключение require
  • Переменные: var (приватные у модулей), exports, global (используется редко)
  • Виды модулей: js, node ( с расширением .node), json (с расширением .json ) . Модули json используются в том случае, когда требуется хранить какую-либо простую информацию на файле.
  • Модуль-директория DIR/index

Объект module

  • Объект module
  • Модуль или приложение? module.parent
  • Модуль-функция module.exports = function
  • Кеширование модулей (заново модуль никогда не читается)
  • Расположение модулей: порядок поиска
  • Передаем параметры: модуль-фабрика

Объект module (основополагающий объект для модулей) является переменной, которая существует в каждом модуле (файле, можно вывести console.log(module);). . Содержимое: свойство id – как правило путь к файлу,
parent – ссылка на родительский модуль (module.parent - ссылка на родительский модуль, который require данный),
children (module.children - те модули, которые подключены посредством require),
свойство exports и другие.

Модуль или приложение? module.parent

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

if(module.parent) {
    exports.run = run;
}
else {
    run();
}

пс: как говорится на stackoverflow.com Родетелем является модуль, который вызвал скрипт для интерпретации

// $ node foo.js
console.log(module.parent); // null

// require('./foo')
console.log(module.parent); // { ... }

Правильное использование module.exports

В контексте модуля:

module.exports = exports = this (данные конструкции равнозначны)

exports и this ссылки на module.exports.

Так как exports и this это всего лишь ссылки на объект, то если у них поменять значение, то они никак не повлияют на module.exports. Поэтому ранее мы использовали такой код: exports.User = User;

Если вы хотите передать функцию не в объекте, а напрямую, то используйте следующий синтаксис:

module.exports = User;

Кеширование модулей

Когда Nodejs загружает модуль он полностью создает соответствующий объект module (с учетом parent, exports и других аналогичных свойств) и запоминает его у себя (module.id (полный путь к файлу) служит идентификатором для внутреннего кэша) и в следующий раз, когда мы повторно обращаемся (подключаем) к какому-либо модулю (файлу), nodejs берет все тот же объект из кэша. То есть, например, инициализировать модуль достаточно 1 раз в каком-либо файле, в дальнейшем его можно просто использовать.

В нашем случае для var db = require("../db");
и для var db = require("./db"); берется один и тот же объект. Поэтому принцип следующий: в первый раз, когда используется модуль, он инициализируется и в дальнейшем мы его только подключаем и пользуемся им (то есть в нашем случае нам не нужно использовать db.connect() дважды, то есть в разных файлах).

Расположение модулей: порядок поиска модулей в nodejs

Как сделать так, чтобы db подключалась всегда без указания специфичного пути:

var db = require("../db"); //или
var db = require("./db"); 

а вот так:

var db = require("db"); 

в независимости от того в каком файле подключается db.

Для этого нужно понимать порядок поиска модулей в nodejs (то что происходит, когда вызывается require). В nodejs существует множество встроенных модулей, например, require("fs");, который будет подключен без проблем. Если же в require указать конкретный путь, например, require("../db");, то поиск будет вестись исходя из заданного пути и файл будет найден, либо nodejs попытается получить этот файл как директорию (и будет искать index.js внутри категории).

Если же указать require("db"); и при этом модуль не является встроенным, то будет произведен поиск директории node_modules относительно текущего положения (если найдет, то попытается взять модуль из нее). Если директория node_modules отсутствует, то директория node_modules будет искаться выше и т.д.

Помимо указания конкретного пути для модуля, nodejs может искать модули следующим образом:

Введение в npm – менеджер пакетов для Node.JS

Модуль npm идет вместе со стандартной установкой node. В этом модуле содержится консольная утилита (npm), которая дает доступ к громадной базе данных модулей. (https://www.npmjs.com/ ) Как правило, если стоит стандартная задача по программированию, то модуль для нее найти не составит труда. Для того чтобы поделиться модулем с другими людьми необходимо:

  1. создать файл с описанием пакета (package.json), который содержит информацию о модуле (имя, версия и т.д.). Либо вручную, либо через команду
    npm init
    (запросит нужную информацию)
  2. Чтобы опубликовать модуль необходимо:
    1. Добавить юзера посредством команды npm adduser (необходимо ввесть Username и Password). Теперь вся работа с npm будет от имени этого пользователя. Юзер может залогинится на https://www.npmjs.com/~name_user и наблюдать за своими модулями.
    2. Публикация: npm publish
  3. Далее кто-либо может использовать Ваш, добавленный в базу, модуль, а сам пользователь вносить изменения.
  4. Получаем все команды npm при помощи команды npm help
  5. Поиск нужно модуля в базе данных: npm s ключевые_слова или npm search ключевые_слова (например, npm s super module)
  6. Устанавливаем модуль: npm install name_module или npm i name_module
  7. При установке модулей nodejs сначала ищет папку node_modules в текущей директории (потом выше и выше и т.д), либо (если node_modules отсутствует) ищет package.json (также поднимаясь вверх; package.json, как правило, обозначает корень проекта) и, соответственно, если находит package.json, то делает в соответствующей директории папку node_modules; если же оба варианта не проходят, то nodejs делает папку node_modules в текущей директории. Если вы хотите поставить модуль в определенную директорию, то в этой директории необходимо создать папку node_modules.
  8. npm up обновить модуль (проверит модули на обновление, которые есть в папке node_modules)
  9. npm remove имя_модуля (удалить модуль)

Вывод по npm:

npm init
nmp adduser
npm publish
npm search ключевые слова
npm install модуль
npm update модуль
npm remove модуль
npm help команда

Структура пакета NPM

Установка нужной версии, например: npm i express@3.0.0

Последнюю версию модуля можно получить в том случае, если модуль разрабатывается, используя систему версинирования git, например, на github. Достаточно получить Git Read-Only (url): https://github.com/strongloop/express.git и в консоли:

npm i https://github.com/strongloop/express.git

dependencies в package.json

dependencies указывает на те модули, от которых зависит данный.

devDependencies

Модули прописанные в devDependencies не ставятся, если модуль подтягивается как зависимость. Они ставятся лишь для разработки и их можно установить, если, например, зайти в модуль в папке node_modules и прописать npm i (или при установке флага npm config).

поле main задает точку входа в пакет

Глобальные модули

Любой модуль можно поставить глобально, если поставить флаг -g: npm -g модуль

Глобально означает в системную директорию.

Директория глобальных модулей под windows:

C:\users\User_Name\AppData\Roaming\npm

Глобальные модули ставятся в стандартную системную директорию. Те бинарники, которые есть в package.json будут поставлены по системному пути (это и есть основное применение глобальных модулей), то есть в дальнейшем их можно будет вызвать через консоль.

По материалам курсов И. Кантора Основные возможности и средства создания веб-сервисов, включая внутренние особенности самого сервера Node.JS

Комментарии к статье

аватарка пользователя
2017-03-15
Татьяна

Спасибо за хорошую статью

аватарка пользователя
2017-03-15
Татьяна

Спасибо за хорошую статью

аватарка пользователя
2017-03-15
Татьяна

Спасибо за хорошую статью

аватарка пользователя
2017-05-10
Алексей

Спасибо, отличная статья, которая открыла глаза на анатомию модулей в node.js

аватарка пользователя
2018-04-30
Борис

Спасибо то спасибо. А вот у меня не получается, я новичок и пытался два первых ппримера выполнить.
Создал index.js

как сказано в примере

./user/index.js
--------------------------//
function User(name){
this.name = name;
}

User.prototype.hello = function(who){
console.log(phrases.Hello + ", " + who.name);
};

exports.User = User;
----------------------//
Подключаем и используем конструктор User в файле ./server.js

//server.js я назвал se.js

var user = require('./user');
....
.....
--------------------///

и при запуске выдает ошибку

bor@debian8-8-0:~/2$ node se
/home/bor/2/user/index.js:6
console.log(phrases.Hello + ", " + who.name);
^

ReferenceError: phrases is not defined
at User.hello (/home/bor/2/user/index.js:6:17)
at Object.<anonymous> (/home/bor/2/se.js:8:7)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:188:16)
at bootstrap_node.js:609:3
bor@debian8-8-0:~/2$