Сентябрь 2015

ТОМ 30 НОМЕР 9

Работающий программист - MEAN: Node.js

Тэд Ньюард | Сентябрь 2015

Тэд Ньюард Microsoft внедряет технологии из широкого спектра программного обеспечения как часть своей политики ребрендинга и «реактуализации» («re-relevancing»). Одной из таких технологий является Node.js. Это дает разработчикам блестящую возможность задействовать один из более популярных полных стеков программного обеспечения на платформе Node.js, известный как MEAN: MongoDB, Express, AngularJS и Node.js.

В выпуске своей рубрики в прошлом номере (msdn.microsoft.com/magazine/mt185576) я собрал базовые части Node.js и подготовил их к работе. В этом выпуске я создам простую конечную веб-точку «Hello World» на основе Node и применю ее к веб-сайту в Microsoft Azure. В последующих статьях я буду постепенно проходить по всему стеку MEAN, каждый раз начиная работу с нуля.

Как обсуждалось в предыдущей статье, части стека MEAN можно было бы заменить на что-то другое: MongoDB на DocumentDB, Node.js на ASP.NET Web API и Express на ASP.NET MVC, AngularJS на BackboneJS (или любую из целого набора других JavaScript-инфраструктур для одностраничных приложений). Но ни одна из альтернатив не имеет такой популярности, как MEAN (по крайней мере, среди приверженцев JavaScript).

Node.js

Node.js — это, по сути, просто «JavaScript на сервере». Да, подход к программированию в Node.js отличается, поскольку эта библиотека пытается обеспечить выполнение с параллельной обработкой. Вместо блокирования на каком-либо вызове программист передает литерал функции, подлежащей вызову по завершении операции. Это позволяет разработчику считать код однопоточным, хотя под поверхностью используется несколько потоков. Но в целом, самое крупное отличие Node.js в том, что вы используете для создания серверных компонентов JavaScript вместо C#, Java или Ruby. В этом смысле это на самом деле лишь смена декораций, а не совершенно иная вселенная.

Самое простое приложение Node.js — это, конечно, вездесущее «Hello, World», которое легко написать, используя встроенный объект console:

console.log("Howdy, NodeJS!");

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

Как и большинство платформ программирования, Node.js изначально имеет свой набор библиотек и API. Как я указывал в прошлый раз, Node.js использует соглашение require для ссылки на установленную библиотеку. Это приводит к захвату возвращаемого объекта в локальную переменную с тем же именем. Поэтому, например, если мне нужно написать простой HTTP-сервер, который в конечном счете будет выдавать мне то же приветствие по протоколу HTTP, я могу поместить следующее в простой файл helloHTTP.js:

var http = require('http');
var port = process.env.PORT || 3000;
http.createServer(function(req, res) {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello World\n');
}).listen(port);

Строка require находит библиотеку http в установке Node.js и сохраняет ее в объекте http как встраиваемую зависимость. Это стандартное соглашение Node.js, и оно должно соблюдаться как нечто священное. Во второй строке используется встроенный объект process для доступа к переменным окружения. В данном случае объект env в объекте process определяет, задано ли какое-то значение переменной окружения PORT. Если да, оно используется как порт, через который работает сервер. В ином случае принимается порт по умолчанию — 3000. Многие инфраструктуры Node.js предпочитают порт 3000 по умолчанию по каким-то туманным историческим и культурным причинам.

Природа программирования в Node.js становится яснее в следующих нескольких строках. С помощью объекта http я создаю HTTP-сервер. Единственный параметр — литерал функции, который принимает объекты req (HTTP-запрос) и res (HTTP-ответ) в качестве параметров; в res записывается возвращаемый HTTP-ответ. Эта идиома вездесуща на всех уровнях стека Node.js.

Это одна из тех вещей, которые «вы любите или ненавидите». В следующих статьях вы увидите больше подобных вещей. Если вам не все здесь ясно, потратьте некоторое время на эксперименты. Затем возвращаемый от createServer объект связывается с нужным портом вызовом listen. И о чудо, вы получаете работающий HTTP-сервер, который можно легко запускать командой node helloHTTP с указанием браузеру адреса http://localhost:3000.

Утилиты командной строки Azure

Из моей прошлой статьи вы вспомните, что Node.js имеет утилиту для работы с пакетами — Node package manager (npm), позволяющий скачивать зависимые библиотеки. Ее также можно использовать для скачивания утилит, которые потом используются, в том числе, из командной строки. Это малоизвестная, но мощная возможность Node.js, причем поддерживаемая на любых платформах.

Любые различия между Windows, Mac OS или Linux можно эффективно скрывать за стеной JavaScript-скриптов. Microsoft выбрала этот вариант некоторое время назад и упаковала набор утилит командной строки в пакет Node.js с именем azure-cli. Его легко установить с помощью npm:

npm install –g azure-cli

Флаг –g указывает npm устанавливать инструментарий глобально (т. е. без привязки к локальному каталогу, в котором выполняется эта команда). Это делает полученный пакет доступным для использования во всей системе. По окончании вы сможете работать с новой утилитой командной строки — azure. Пакет azure-cli дает ровно ту же функциональность, что и Azure Portal. Преимущества azure-cli заключаются в ее способности помещать команды azure в скрипт как часть, например, системы автоматизированного развертывания.

Развертывание в Azure

Таким образом, если вы хотите, чтобы это прекрасное приветствие было доступно всему миру по Интернету, вам нужно создать Azure Web Site в качестве хоста. С помощью утилиты azure это довольно легко. Сначала вы должны связать эту утилиту с учетной записью в Azure:

azure account download

Это направит браузер по умолчанию в системе на портал входа в Azure. Для входа используйте удостоверения по учетной записи Azure. После этого будет автоматически загружен файл publishSettings, содержащий информацию об удостоверениях, нужных утилите azure, и эту информацию можно импортировать напрямую:

azure account import <filename>

В качестве filename часто используется нечто вроде «Visual Studio Ultimate with MSDN-4-23-2015-credentials.publishsettings» — в зависимости от деталей подписки Azure и даты скачивания вами файла publishSettings. По окончании создание нового веб-сайта Azure будет заключаться в простой настройке Git на выполнение развертываний на этом сайте:

azure site create –git

Эта команда запросит имя сайта и (предполагая, что это имя уникально) запустит соответствующий веб-сайт. Если все это работает, задайте текущий каталог как локальный репозитарий, инициализируемый Git. Предполагая, что вы все еще находитесь в том же каталоге, где содержится ранее созданный файл helloHTTP.js, этот файл можно добавить в репозитарий Git и передать в облако Azure:

git add helloHTTP.js
git commit –m "Initial commit"
git push azure master

Git задумается на несколько секунд. Потом выполнить последовательность шагов, которые пока останутся скрытыми. Но по окончании в Azure будет содержаться новый код Node.js, и вы сможете перейти к нему, как показано на рис. 1.

«Hello, Node World»
Рис. 1. «Hello, Node World»

Вот почему код helloHTTP использует либо порт 3000 по умолчанию, либо переменную окружения PORT из окружающего процесса. В облаке Azure переменной PORT присваивается значение, поддерживаемое инфраструктурой Azure. Благодаря этому Microsoft может эффективнее управлять конечными точками различных сервисов.

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

С этого момента почти все будет связано с MEAN. Единственный случай, когда вам потребуется держать в уме детали Azure, — конфигурирование среды, например, для указания на сервер базы данных MongoDB или для обработки взаимодействия Azure с Node.js.

Заключение

Стоит отметить, что Node.js — это не просто HTTP-конвейер. По сути, Node может выполнять любой вид сетевого приложения, открывая подходящую библиотеку. То же самое относится и к Microsoft .NET Framework. Однако, как и в случае .NET Framework, большинство приложений Node.js будут по своей природе основываться на HTTP.

Библиотека http в Node.js является довольно низкоуровневой. В итоге сообщество Node.js разработало библиотеку более высокого уровня и набор абстракций для упрощения работы с конечными точками на основе HTTP. Эта библиотека — Express. Она позволяет создавать то, что в сообществе Node.js называют промежуточным ПО (middleware). Именно об этом мы т поговорим в следующий раз.

Поэкспериментируйте пока с библиотекой http в Node.js, но не увлекайтесь слишком сильно, потому что очень скоро я оставлю ее в покое — уже на следующей итерации. А тем временем…

Удачи в кодировании!


Тэд Ньюард (Ted Neward) — директор iTrellis по технологиям (эта компания предоставляет консалтинговые услуги). Автор и соавтор многочисленных книг, в том числе «Professional F# 2.0» (Wrox, 2010), более сотни статей, часто выступает на многих конференциях по всему миру; кроме того, имеет звание Microsoft MVP в области F#. С ним можно связаться по адресу ted@tedneward.com или ted@itrellis.com.

Выражаю благодарность за рецензирование статьи эксперту Шону Уайлдермуту (Shawn Wildermuth).