Express, Node-фреймворк

Express является фреймворком для приложений Node.js.

Express — это минималистичный и гибкий Node-фреймворк для веб-приложений, который предоставляет широкий набор функций для создания одной или множества страниц и гибридных веб-приложений.

Для Express имеется богатый API и он ЧЕРТОВСКИ БЫСТРЫЙ!!!

Express, как хорошо известно, развивается своим путём, в отличие от других фреймворков, во многом опирающихся на Rails, но также много позаимствовал из другого Ruby-фреймворка под названием Sinatra. Концепция простая: фреймворк предоставляет достаточно возможностей для запуска и работы «на лету», не требуя много времени на подготовку.

В этом руководстве мы будем использовать Express в качестве основного инструмента для получения веб-приложения и запуска его с сервером, поддержки маршрутов, страницы ошибок, ведение логов и т. д.

Установка Express

Установка Express с npm действительно простая. Имейте в виду, что в Express есть две части — это библиотека для его запуска и замечательный генератор приложения.

Установка Express:

$ npm install express -g

Установка генератора:

$ npm install express-generator -g

Версия генератора

Express 4.0 был выпущен недавно и есть те, кто с ним не дружат. В npm содержится способ указать определённую версию генератора для установки.

$ npm install -g express-generator@3

Создание нового Express-приложения

На данный момент вы должны быть готовы двинуться вперёд и создать приложение. В этом примере мы создадим приложение Node.js с фреймворком Express.

$ express <ваше приложение>

Выполнив эту команду (используя demo-app в качестве примера) вы должны увидеть следующее:

create : demo-app
create : demo-app/package.json
create : demo-app/app.js
create : demo-app/public
create : demo-app/public/javascripts
create : demo-app/public/images
create : demo-app/public/stylesheets
create : demo-app/public/stylesheets/style.css
create : demo-app/routes
create : demo-app/routes/index.js
create : demo-app/routes/users.js
create : demo-app/views
create : demo-app/views/index.jade
create : demo-app/views/layout.jade
create : demo-app/views/error.jade
create : demo-app/bin
create : demo-app/bin/www

install dependencies:
  $ cd demo-app && npm install

run the app:
  $ DEBUG=my-application ./bin/www

БУМ! Express берёт на себя часть работы. Теперь мы делаем то, что сказали компьютеру — изменить текущую папку на папку приложения и запустить npm install.

Что в этом приложении?

В этот момент вы можете увидеть новую структуру приложения, которая была создана для вас.

app.js
node_modules/ 
public/   
views/
bin/    
package.json  
routes/

app.js

Это логичная отправная точка для вашего приложения. В ней есть несколько вещей, о которых стоит поговорить:

Следующие строки для этого типа приложения нам не понадобятся:

var user = require('./routes/user');
app.get('/users', user.list);

Устанавите путь к папке, где хранятся файлы представления:

app.set('views', path.join(__dirname, 'views'));

Установите путь к папке со статичными ресурсами:

app.use(express.static(path.join(__dirname, 'public')));

Установите корневой маршрут для приложения:

app.use('/', routes);

node_modules/

Это папка, где будут находиться все ваши пакеты npm.

public/

Папка для всех статичных ресурсов, например, изображений, JavaScript, CSS, шрифтов и др.

views/

Здесь будут жить все ваши макеты и файлы представления Jade.

bin/

Здесь хранится единственный файл www и он активирует Node.

package.json

Описание проекта, менеджер скриптов и манифест приложения. Обратите внимание на следующий объект:

"scripts": {
  "start": "node ./bin/www"
},

Это код, который позволяет вам запускать npm start для приложения.

routes/

Это папка, в которой вы будете строить маршруты REST для вашего приложения. После базовой установки здесь должны находиться два файла: index.js и users.js.

Веселье с маршрутами

Методы app.VERB() обеспечивают функциональность маршрутизации в Express, где VERB является одним из методов HTTP, вроде app.post(). Можно установить несколько функций обратного вызова, все они рассматриваются одинаково и ведут себя как промежуточное программное обеспечение, с одним исключением, что все эти функции могут вызывать next('route') в обход оставшегося маршрута. Этот механизм может быть использован для выполнения предварительных условий для маршрута, затем передать управление в последующие маршруты, когда нет никаких причин для обработки совпадений маршрута.

Следующий фрагмент иллюстрирует возможно самое простое определение маршрута. Express переводит строку пути в регулярные выражения, используемые внутри для сравнения с входящими запросами. Строки запроса не учитываются при выполнении этих совпадений, например GET/ будет соответствовать следующему маршруту GET/?name=tobi.

app.VERB(path, [callback...], callback)

Давайте получим в настройках несколько маршрутов. В файле app.js следующая строка показывает, как они работают вместе:

var routes = require('./routes/index');

Что здесь происходит? В принципе, Express устанавливает переменную routes чтобы она затребовала путь и файл ./routes.index.

Эта переменная затем используется для установки корневого пути приложения:

app.use('/', routes);

Ещё одну вещь, которую мы можем сделать — это res.send() и что мы сюда положим, то и будет передаваться непосредственно в браузер. Например:

router.get('/foo', function(req, res){
  res.send('hello world');
});

Используя res.send() мы можем сделать забавные вещи, вроде отправки в объекты JSON.

router.get('/foo', function(req, res){
  res.send({'name':'Bob Goldcat', 'age': '41'})
});

Этот метод позволяет сохранить все наши маршруты в файл index.js, если это необходимо. Есть более эффективные способы для решения более сложных задач маршрутизации, но в рамках этой работы и так хорошо.

Что в файле index.js?

Взглянув на наш файл index.js вы должны увидеть следующее:

var express = require('express');
var router = express.Router();

/* Получить главную страницу. */
router.get('/', function(req, res) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

router.get

Это функция, которая получит адрес пути /. Затем нам нужно создать функцию, которая будет делать req (запрос) и res (ответ). Другая концепция next для цепочки событий также хорошо подошла бы сюда, но не показана в данном примере.

Что такое module.exports?

Это объект, который возвращается как результат запрашиваемого вызова. Эта особенность Node, больше о ней написано здесь.

Построение нового маршрута

Глядя на шаблон синтаксиса, если мы хотим добавить новый маршрут в приложение, то можем просто сделать что-то вроде следующего:

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

Это маршрут? Это контроллер?

Самое интересное что маршрут это функция, содержащая логику. Внутри маршрута находится функция res.render:

res.render('foo', { title: 'Express' });

В шаблоне представления мы видим это:

h1= title
p Добро пожаловать в #{title}

Это два примера того, как мы можем вытащить данные из controller/route и вывести их в представлении. В этом примере мы выводим HTML:

<h1>Express</h1>
<p>Добро пожаловать в Express</p>

Всё это, кажется, вытекает из проблемы — может ли маршрут также содержать информацию контроллера? Это верно, поэтому есть движение в обществе за то, чтобы изменить имя папки с routes на controllers.

Отличный пример этого можно увидеть в примере Express MVC.

Но ради логичности в этом руководстве мы будем держаться текущих соглашений.

Ошибки 404

Ошибки уже направляют вас в Express. В файле app.js есть следующее:

/// поймать 404 и перенаправить в обработчик ошибки
app.use(function(req, res, next) {
  var err = new Error('Не найдено');
  err.status = 404;
  next(err);
});

В папке views/ есть errors.jade.

extends layout

block content
  h1= message
  h2= error.status
  pre #{error.stack}

Всё просто. Если вы хотите настроить свою страницу 404, то всего-лишь редактируйте это представление.

Автор: Дейл Санде
Последнее изменение: 17.04.2016
Редакторы: Влад Мержевич, Клим Щербаков