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/ ) Как правило, если стоит стандартная задача по программированию, то модуль для нее найти не составит труда.
Для того чтобы поделиться модулем с другими людьми необходимо:
- создать файл с описанием пакета (
package.json
), который содержит информацию о модуле (имя, версия и т.д.). Либо вручную, либо через командуnpm init
(запросит нужную информацию) - Чтобы опубликовать модуль необходимо:
-
Добавить юзера посредством команды
npm adduser
(необходимо ввестьUsername
иPassword
). Теперь вся работа с npm будет от имени этого пользователя. Юзер может залогинится наhttps://www.npmjs.com/~name_user
и наблюдать за своими модулями. - Публикация:
npm publish
-
Добавить юзера посредством команды
- Далее кто-либо может использовать Ваш, добавленный в базу, модуль, а сам пользователь вносить изменения.
- Получаем все команды npm при помощи команды
npm help
- Поиск нужно модуля в базе данных:
npm s ключевые_слова
илиnpm search ключевые_слова
(например,npm s super module
) - Устанавливаем модуль:
npm install name_module
илиnpm i name_module
- При установке модулей nodejs сначала ищет папку
node_modules
в текущей директории (потом выше и выше и т.д), либо (еслиnode_modules
отсутствует) ищетpackage.json
(также поднимаясь вверх;package.json
, как правило, обозначает корень проекта) и, соответственно, если находит package.json, то делает в соответствующей директории папкуnode_modules
; если же оба варианта не проходят, то nodejs делает папкуnode_modules
в текущей директории. Если вы хотите поставить модуль в определенную директорию, то в этой директории необходимо создать папкуnode_modules
. npm up
обновить модуль (проверит модули на обновление, которые есть в папкеnode_modules
)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
Комментарии к статье
Спасибо за хорошую статью
Спасибо за хорошую статью
Спасибо за хорошую статью
Спасибо, отличная статья, которая открыла глаза на анатомию модулей в node.js
Спасибо то спасибо. А вот у меня не получается, я новичок и пытался два первых ппримера выполнить.
Создал 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$