node.js для Java-разработчиков: первые шаги

f91c5cfe26e84272803ac6468c3942d7.jpegУ опытного программиста, сталкивающегося с новой технологией для решения конкретной прикладной задачи, сразу возникает множество практических вопросов. Как правильно установить платформу? Где и что будет лежать после установки? Как создать каркас проекта, как он будет структурирован? Как разбивать код на модули? Как добавить библиотеку в проект? Где вообще взять готовую библиотеку, которая делает то, что нужно? Как и в чём отлаживать код? Как написать модульный тест? Ответы на эти вопросы можно при желании легко найти в сети, но придётся перечитать дюжину статей, и на каждый вопрос ответов будет, скорее всего, несколько. Некоторое время назад мне понадобилось написать небольшой туториал по node.js, который бы позволил быстро запустить разработку и познакомить новых программистов в проекте с этой технологией. Рассчитан он на опытных Java-разработчиков, которые и язык JavaScript хорошо знают, но node.js как платформа для бэкэнда для них в новинку.

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

ec2eb4735a834eb78bf82b00c21cde99.jpeg

Установка и настройкаУстановка node и npm Windows Установка node.js под Windows производится с помощью msi-инсталлятора. Для его загрузки нужно перейти на сайт https://nodejs.org и щёлкнуть «Install». После скачивания инсталлятора (файл с именем вида node-v0.12.4-install.msi) необходимо запустить его и следовать инструкциям по установке.a527f7aa432f4fcf9578b28da03c1325.png

По умолчанию под Windows node.js устанавливается в папку c:\Program Files\nodejs. Также по умолчанию устанавливаются все компоненты (собственно node.js, пакетный менеджер npm, ссылка на документацию; кроме того, путь к node и npm прописывается в переменную среды PATH). Желательно убедиться, что все компоненты установки выбраны.

cbf7062edb974841b26f142bbb43d05c.png

OS X В OS X проще всего установить node через менеджер пакетов brew. Для этого необходимо выполнить команду: > brew install node Node установится в папку /usr/local/Cellar//node с постоянным симлинком /usr/local/opt/node/.Ubuntu (x64) Для установки последней ветки (0.12) лучше скачать дистрибутив с сайта: wget http://nodejs.org/dist/v0.12.4/node-v0.12.4-linux-x64.tar.gz sudo tar -C /usr/local --strip-components 1 -xzf node-v0.12.4-linux-x64.tar.gz Дистрибутив распакуется в папку /usr/local в подпапки bin, include, lib и share.Проверка установки Для проверки корректности установки можно запустить в командной строке node и npm с параметром --version: > node --version v0.12.4 > npm --version 2.10.1 Установка плагина в IntelliJ IDEA Запустим IntelliJ IDEA, зайдём в настройки.53484914047f4e339dcb1bb32b2d88f6.png

Найдём раздел Plugins и щёлкнем «Install JetBrains Plugin…»

019ffcbc01d548828bf9a164a2938d31.png

Найдём в списке плагин NodeJS, щёлкнем по кнопке «Install Plugin». По окончании загрузки кнопка превратится в «Restart IntelliJ IDEA» — щёлкнем её для перезагрузки среды.

4e40285800ef4b4695ef3f0c25fed8b1.png

После перезагрузки зайдём в настройки и найдём раздел Languages & Frameworks → Node.js and NPM. Убедимся, что в разделе «Node interpreter» указана ссылка на установленный исполняемый файл node.

370d863bd70740cdb3b6da4961589a4f.png

В разделе «Sources of node.js Core Modules» щёлкнем кнопку «Configure». В появившемся окне выберем «Download from the Internet» и щёлкнем «Configure», при этом скачаются и проиндексируются исходники node.js. Это позволит просматривать исходники при разработке.

7200ebc417f841a28c9041a85a0315a5.png

В разделе packages отображаются глобально установленные пакеты (см. раздел «Глобальные пакеты»). В этом окне можно добавлять, удалять и обновлять эти пакеты. Если рядом с именем пакета отображается синяя стрелочка, значит, доступно обновление. Глобально лучше устанавливать только пакеты-утилиты.

Первые шаги Пишем «Hello World» Создадим файл app.js, который формирует и выводит соответствующую строчку в консоль: // файл app.js var greeting = 'hello'; greeting += ' world!'; console.log (greeting); Запустим его командой: > node app.js hello world! Используем REPL Запустив команду node без аргументов, можно попасть в REPL-цикл, аналогичный браузерной JS-консоли. В нём можно выполнять и проверять фрагменты кода: > node > console.log («hello world!») hello world! undefined

> [1, 2, 3].reduce (function (sum item){return sum + item}, 0) 6 Каждая выполненная строчка имеет возвращаемый результат, который также выводится в консоль. Функция console.log () не возвращает результата, поэтому после её вызова в консоли вывелось «undefined».В REPL-консоли работает автодополнение по нажатию клавиши Tab. Например, если написать «console.» и нажать Tab, то отобразится список атрибутов и функций объекта console.

> console. console.__defineGetter__ console.__defineSetter__ console.__lookupGetter__ console.__lookupSetter__ console.__proto__ console.constructor console.hasOwnProperty console.isPrototypeOf console.propertyIsEnumerable console.toLocaleString console.toString console.valueOf

console.assert console.dir console.error console.info console.log console.time console.timeEnd console.trace console.warn console.Console console._stderr console._stdout console._times

> console. Для выхода из консоли можно нажать Ctrl+D.Работа с npm Инициализация проекта Для инициализации проекта выполним в каталоге будущего проекта команду npm init и введём необходимые данные в интерактивном режиме (можно просто нажимать Enter, так как предлагаются внятные настройки по умолчанию): > npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields and exactly what they do.

Use `npm install --save` afterwards to install a package and save it as a dependency in the package.json file.

Press ^C at any time to quit. name: (nodetest) version: (1.0.0) description: my first node application entry point: (index.js) app.js test command: git repository: keywords: author: license: (ISC) About to write to ***\package.json: { «name»: «nodetest», «version»:»1.0.0», «description»: «my first node application», «main»: «app.js», «scripts»: { «test»: «echo \«Error: no test specified\» && exit 1» }, «author»:», «license»: «ISC» }

Is this ok? (yes) По окончании выполнения утилиты в текущем каталоге будет создан файл package.json, описывающий конфигурацию проекта. В нём же будет храниться информация о зависимостях проекта.Добавление пакетов-зависимостей в проект Чтобы установить зависимость в проект, используется команда npm install. При этом в текущем каталоге будет создана папка node_modules, в которую будет помещён загруженный пакет. Ключ --save означает, что информация об этой зависимости будет добавлена также в package.json. Например, установим пакет log4js для протоколирования: > npm install log4js log4js@0.6.25 node_modules/log4js ├── async@0.2.10 ├── underscore@1.8.2 ├── semver@4.3.4 └── readable-stream@1.0.33 (isarray@0.0.1, inherits@2.0.1, string_decoder@0.10.31, core-util-is@1.0.1) После выполнения этой команды обнаружим, что в текущем каталоге появилась папка node_modules\open, а в файле package.json добавилась запись: «dependencies»: { «log4js»:»0.6.25» } Запись о зависимости можно добавить в файл package.json и вручную, но после этого необходимо выполнить npm install, чтобы загрузить указанную зависимость в каталог node_modules.Глобальные пакеты Пакеты можно устанавливать как в каталог проекта, так и глобально, тогда они будут видны для всех проектов. Как правило, глобально устанавливаются только пакеты, являющиеся утилитами, например, утилита управления зависимостями bower, сборщики gulp и grunt, генератор проектов на Express express-generator, и т.д. Глобальные пакеты устанавливаются:

В Windows 8 — в %USERPROFILE%\AppData\Roaming\npm\node_modules, В OS X — в /usr/local/lib/node_modules, В Ubuntu — в /usr/local/lib/node_modules. Чтобы установить пакет глобально, команда npm выполняется с ключом -g:

npm install -g grunt Работа в IntelliJ IDEA Открытие проекта Чтобы открыть проект на node.js, достаточно открыть папку, содержащую package.json.9af13f9379864db1a255237aa6c4128f.png

Настройка конфигурации запуска Для запуска и отладки в IntelliJ IDEA необходимо создать конфигурацию запуска. Для этого зайдём в Run → Run Configurations, щёлкнем плюсик в левом верхнем углу и выберем node.js: eeafc357c9cb4c3e8910b6581b08a2c6.png

Заполним поля Name и JavaScript File:

4ac8efab5de24cc6bee09eb88e4197a2.png

Теперь можно запускать скрипт в обычном режиме и в режиме отладки с помощью соответствующих кнопок на панели инструментов:

6af8b3d07b674d64bd8ddc8ace3f698b.png

Отладка Для отладки необходимо запустить созданную конфигурацию в режиме Debug. При этом можно ставить брейкпойнты на строки, «шагать» по строкам, смотреть содержимое стека вызовов, значения переменных в текущем контексте и делать всё прочее, что ожидается от отладочного режима.b106ceeda38342bb8e9ca23ce17b0787.png

Модульность в node.js В Java единицами модульности являются пакеты и классы. Единицей модульности в node.js является файл. Чтобы сделать импорт одного модуля в другой, используется модуль-локальная (т.е. неявно определённая в каждом модуле) функция require (). Стандартные модули или пакеты, установленные в node_modules, можно импортировать по простому имени: var http = require ('http'); В переменную http будет помещён объект, который был экспортирован модулем http.Если требуется импортировать не стандартный модуль, а один из модулей проекта в другой, то аргумент для функции require () должен содержать размещение модуля относительно текущего модуля (не считая расширения .js), например:

// файл myproject/somedir/mymodule1.js mymodule2 = require (»…/anotherdir/mymodule2»); mymodule2.fun (); // файл myproject/anotherdir/mymodule2.js module.exports.fun = function () { console.log («hello world!»); } Всё, что объявлено в файле модуля, видно только внутри него — за исключением того, что мы явно экспортируем. Например, в отличие от JavaScript в браузере, область видимости переменной, объявленной на верхнем уровне, ограничена тем модулем, в котором она объявлена: // файл mymodule.js var enterprise = 'bloody'; Переменная enterprise будет видна только внутри модуля mymodule.js.Чтобы экспортировать что-либо из модуля, можно использовать доступный в любом модуле атрибут module.exports, который по умолчанию содержит в себе пустой объект. Можно также использовать сокращённую ссылку на него — модуль-локальную переменную exports. Функция require (), которой передано имя нашего модуля, будет возвращать то, что мы поместили в module.exports. Соответственно, если мы поместим туда такой объект:

// файл mymodule.js module.exports = { fun: function () { console.log ('hello world!'); } } То именно его вернёт функция require, будучи вызванной в другом модуле: // файл mymodule-client.js mymodule = require ('./mymodule'); mymodule.fun (); Полученный объект mymodule — это тот же самый объект с функцией fun, который был присвоен атрибуту module.exports в нашем модуле.Однако подобным способом сделать экспорт не получится:

// файл mymodule.js exports = { fun: function () { console.log ('hello world!'); } } Это связано с тем, что из модуля всегда экспортируется атрибут module.exports. Заменив сокращённую ссылку exports на другой объект, мы не изменили этот атрибут. Сокращённая ссылка exports может быть использована только для экспорта каких-то отдельных функций или атрибутов: // файл mymodule.js exports.fun = function () { console.log ('hello world!'); } // файл mymodule-client.js require ('./mymodule').fun (); Тестирование Mocha Для добавления модульного тестирования в проект лучше всего начать с фреймворка Mocha. Устанавливается он как глобальный npm-модуль: npm install -g mocha Протестируем модуль с простейшей функцией: // файл mymodule.js exports.fun = function (name) { return 'Привет, ' + name + '!'; } Тесты mocha по умолчанию размещаются в подпапке test: // файл test/mymodule-test.js var assert = require ('assert'); var mymodule = require ('…/mymodule');

describe ('mymodule', function () { describe ('#fun ()', function () { it ('должна приветствовать пользователя, имя которого передано как аргумент', function () { assert.equal (mymodule.fun ('Сергей'), 'Привет, Сергей!'); }); }); }); Первый аргумент функции describe — это человекочитаемое описание поведения тестируемой функции или модуля, которое будет выводиться в консоль при прогоне тестов. Здесь желательно придерживаться некоторых структурных соглашений — например, в первом describe указывается имя модуля, во вложенном — имя тестируемой функции. Запустим mocha и убедимся, что тест нашей функции проходит: > mocha

mymodule #fun () ✓ должна приветствовать пользователя, имя которого передано как аргумент

1 passing (7ms) Использование Mocha в IntelliJ IDEA Mocha также умеет мониторить исходники и автоматически прогонять тесты при изменении кода. Запустить её в таком режиме можно и из командной строки с помощью параметра запуска --watch, но раз уж мы строим наш рабочий процесс в IntelliJ IDEA, то используем для этого специальную конфигурацию запуска: 0137cf29e42a46aaada012f989e87733.png

В окне настройки конфигурации запуска укажем название этой конфигурации (Name), а также путь к папке с тестами (Test directory). Сохраним конфигурацию.

c9dc69833b5f435eb688bf61c6516c8c.png

Изменим код функции так, чтобы он не проходил, и выполним (Run) конфигурацию запуска Mocha.

dade14d3393349f899bbcdf6694890a2.png

Теперь щёлкнем кнопку Toggle auto-test в появившейся панели. Эта кнопка включает режим автоматического прогона тестов при изменении исходников.

3fc0aeb2ff5d408bbe9bed40385606f9.png

Исправим код функции, при этом Mocha автоматически прогонит тест и покажет, что теперь всё хорошо:

b7fb9b58937a4b67a264dfd7823f19f8.png

Ресурсы

© Habrahabr.ru