Fork me on GitHub

2. Установка Node.js и создание базового приложения

Добро пожаловать во вторую часть руководства по созданию веб-приложения с помощью Node.js. В рамках серии уроков будет рассказано про основные особенности и трудности, которые возникают при работе с Node.js.

Первая часть руководства была вводной и объясняла логику выбора библиотек для Node.js приложений.

Данная часть сериии освящает процесс установки необходимых пакетов и библиотек. Кроме того, в рамках урока будет создан и проанализирован остов будущего приложения.

2.1. Требования

Наш проект имеет следующие зависимости:

  • Node.js
  • MongoDB
  • npm

Далее я пройдусь по каждому пункту и расскажу о том, как выполнить установку. Логика выбора этих пакетов/библиотек описана в первой части.

2.2. Установка Node.js

Если Node.js еще не установлен, то необходимо скачать исходный код и распокавать его. Я пользуюсь версией 0.2.4. Существует много различных способов установки (deb-пакеты, homebrew и прочие), но основным способом является установка из исходных кодов, для чего в распакованной директории необходимо выполнить:

./configure
make
make install

Возможно, перед запуском make install придется изменить права доступа к директории, либо использовать sudo или su.

Примечание

Альтернативный вариант изложения процесса установки можно найти в Руководстве для начинающих по Node.js от Felix’a. (прим. переводчика)

Эти шаги актуальны только для *nix-систем. Если Вы работаете в Windows, то Вам придется самостоятельно освоить этот процесс, ибо запуск Node.js под Windows возможен.

2.3. MongoDB

В качестве базы данных я хочу использовать MongoDB. Установка не должна вызывать трудностей, так как на сайте доступно много бинарных пакетов и компиляция достаточно проста.

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

mkdir -p /data/db

Это - путь по-умполчанию, но его легко изменить. При разработке я использую значение по-умолчанию.

Дальнейшие инструкции по установке можно получить в MongoDB Quickstart Guide или MongoDB быстрый старт. О том, что и как делается в монго кратко описано в The Little MongoDB Book.

2.4. npm

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

Если Вы разрабатываете на своей машине, то Вам необходимо выполнить:

chown -R $USER /usr/local
curl http://npmjs.org/install.sh | sh

В качестве альтернативы, Вы можете собрать Node.js с префиксом в Вашем домашнем каталоге:

./configure --prefix=~/local

npm “увидит” это и установит npm рядом с Node.js. Более подробная инструкция есть в gist 579814.

Примечание

Помощником в процессе установки Node.js / npm может стать утилита nodeenv, которая позволяет производить иснталляцию в любую указанную директорию, куда есть доступ на чтение. А так же позволяет тиражировать програмное окружение, сохраняя список версий становленных пакеты в файл. (прим. переводчика)

2.5. Node.js пакеты

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

npm install express mongoose jade less expresso

Не пугайтесь многословности npm. Сообщения достаточно просты. Самое главное - убедиться, что для каждого пакета будет написано Success.

2.6. Простое Express-приложение с MongoDB

При работе с MongoDB, я обычно запускаю локальный сервер. Это достаточно просто:

mongod

В результате будет выведен используемый порт, который необходимо запомнить, чтобы прописать его в настройку соединения Mongoose.

В составе Express идет утилита для создания приложений. Чтобы сгенерировать скелет приложения, необходимо перейти в требуемую директорию и выполнить:

express nodepad

Чтобы посмотреть результат, необходимо выполнить:

node app.js

и перейти по адресу http://localhost:3000.

2.7. Анализ скелета Express-приложения

Первая строчка - это стандартный CommonJS: загружается модуль express, создается приложение и экспортируется во вне. Последнее делается для облегчения тестирования, так что не беспокойтесь, если данный пункт пока не понятен.

За последний год Express сильно изменился, так что будьте осторожными со старыми руководствами, так как в них может использоваться устаревшее API. В качестве среднего слоя был добавлен фреймворк connect. Что позволило определенным частям HTTP стека и фреймворков быть взаимозаменяемыми. Так же множество изменений получил и процесс настройки приложения.

Вот что Вы должны увидеть:

app.configure(function() {
  app.set('views', __dirname + '/views');
  app.use(express.bodyDecoder());
  app.use(express.methodOverride());
  app.use(express.compiler({
      src: __dirname + '/public',
      enable: ['less'] }));
  app.use(app.router);
  app.use(express.staticProvider(__dirname + '/public'));
});

По-умолчанию Express приложения очень простые:

  • указывается путь к представлениям
  • обработчик статических файлов задается через staticProvider
  • express.bodyDecoder используется для расшифровки application/x-www-form-urlencoded данных (то есть, форм)
  • средний слой methodOverride позволяет Express приложениям вести себя как RESTful приложения (которые так популяризуются в Rails). Такие HTTP-методы, как PUT, могут быть использованы с помощью скрытых полей (hidden input). Вокруг этой возможности было много дискуссий. Вероятно, поэтому Holowaychuk сделал её опциаональной.

Основной код приложения использует jade для генерации HTML и выставляет переменные для дальнейшей передачи в шаблон:

app.get('/', function(req, res) {
  res.render('index.jade', {
    locals: {
        title: 'Express'
    }
  });
});

Этот вызов определяет путь и соответствующий HTTP-метод: GET и ‘/’. Это означает, что этот кусок кода не будет обрабатывать POST к ‘/’.

Последние несколько строк так же достаточно интересны: проверяется, выполняется ли текущее приложение непосредственно или импортируется другим модулем:

if (!module.parent) {
  app.listen(3000);
  console.log("Express server listening on port %d", app.address().port)
}

Повторюсь - этот подход облегчает тестирование и не стоит волноваться, если Вам он кажется странным.

2.8. Подключение MongoDB

Mongoose позволяет легко делать простые классы - обертки над коллекциями MongoDB. Для начала необходимо загрузить библиотеку и инициализировать соединение с базой данных:

mongoose = require('mongoose').Mongoose
db = mongoose.connect('mongodb://localhost/nodepad')

Я сделал файл моделей с примером:

var mongoose = require('mongoose').Mongoose;

mongoose.model('Document', {
  properties: ['title', 'data', 'tags'],

  indexes: [
    'title'
  ]
});

exports.Document = function(db) {
  return db.model('Document');
};

В app.js модели могут быть импортированы следующим образом:

Document = require('./models.js').Document(db);

Тут передается соединение с базой данных, так что db.model вернет экземпляр модели, основанной на декларации mongoose.model('Document', ...). Мне кажется, что размещение моделей в отдельном файле делает поведение Mongoose немного непрозрачным, но облегчает понимание кода контролера.

2.9. Шаблоны

Генератор Express использует Jade по умолчанию и создает следующий шаблон:

h1= title
p Welcome to #{title}

Код похож на Haml и значительно менее засорен по сравнению с HTML шаблонами. Если же Вы предпочитаете простой HTML, то можете использовать ejs-шаблонизатор.

2.10. Запуск тестов

Генератор Express кроме всего прочего так же создает скелет для тестов. Запустить тесты можно выполнив:

expresso

2.11. Исходный код

Исходный код приложения доступен на alexyoung/nodepad. С исходным кодом текущей части можно ознакомиться в коммите 904d3a1.

2.12. Заключение

После прочтения данной части Вы не должны испытывать проблем в установке окружения для разработки c Node.js, npm и MongoDB. У Вас так же должен быть сгенерирован скелет Express приложения. Вы должны понимать, как оно работает и как запускать Expresso тесты.