Treinamento de Express e Node.js do StrongLoop

Esta tradução fornecida pelo StrongLoop / IBM.

Este documento pode estar desatualizado em relação à documentação em Inglês. Para obter as atualizações mais recentes, consulte a documentação em Inglês.

Migrando para o Express 4

Visão Geral

Express 4 é uma alteração de ruptura do Express 3. Isso significa que um aplicativo Express 3 existente não irá funcionar se você atualizar a versão do Express nas suas dependências.

Este artigo cobre:

Mudanças no Express 4

Existem várias mudanças significativas no Express 4:

Consulte também:

Mudanças no núcleo e sistemas middleware do Express

O Express 4 não depende mais do Connect, e remove todos os middlewares integrados do seu núcleo, exceto pela função express.static. Isso significa que o Express é agora um framework web de middleware e roteamento independente, e que o versionamento e as liberações do Express não são mais afetadas por atualizações nos middlewares.

Sem os middlewares integrados, você deve incluir explicitamente todos os middlewares necessários para a execução do seu aplicativo. Simplesmente siga esses passos:

  1. Instale o módulo: npm install --save <module-name>
  2. No seu aplicativo, solicite o módulo: require('module-name')
  3. Use o módulo de acordo com sua documentação: app.use( ... )

A tabela a seguir lista os middlewares do Express 3 e suas contrapartes no Express 4.

Express 3Express 4
express.bodyParser body-parser + multer
express.compress compression
express.cookieSession cookie-session
express.cookieParser cookie-parser
express.logger morgan
express.session express-session
express.favicon serve-favicon
express.responseTime response-time
express.errorHandler errorhandler
express.methodOverride method-override
express.timeout connect-timeout
express.vhost vhost
express.csrf csurf
express.directory serve-index
express.static serve-static

Aqui está a lista completa de middlewares do Express 4.

Na maioria dos casos, é possível simplesmente substituir a antiga versão 3 do middleware pela sua contraparte do Express4. Para obter detalhes, consulte a documentação do módulo no GitHub.

O app.use aceita parâmetros

Na versão 4 é possível utilizar uma variável de parâmetro para definir o caminho onde as funções do middleware estão carregadas, e em seguida ler o valor do parâmetro a partir do manipulador de rota. Por exemplo:


app.use('/book/:id', function(req, res, next) {
  console.log('ID:', req.params.id);
  next();
});

O sistema de roteamento

Os aplicativos agora carregam implicitamente middlewares de roteamento, para que não seja mais necessário se preocupar com a ordem em que os middlewares são carregados no que diz respeito ao middleware router.

A forma como as rotas são definidas são as mesmas, mas o sistema de roteamento possui dois novos recursos para ajudá-lo a organizar suas rotas:

O método app.route()

O novo método app.route() permite que sejam criados manipuladores de rotas encadeáveis para um caminho de rota. Como o caminho é especificado em uma localização única, criar rotas modulares é útil, já que reduz redundâncias e erros tipográficos. Para obter mais informações sobre rotas, consulte a documentação do Router() .

Aqui está um exemplo de manipuladores de rotas encadeáveis que são definidos usando a função app.route().


app.route('/book')
  .get(function(req, res) {
    res.send('Get a random book');
  })
  .post(function(req, res) {
    res.send('Add a book');
  })
  .put(function(req, res) {
    res.send('Update the book');
  });

classe express.Router

O outro recurso que ajuda na organização das rotas é uma nova classe, express.Router, que pode ser usada para criar manipuladores de rotas modulares montáveis. Uma instância de Router é um middleware e sistema de roteamento completo; por essa razão ela é frequentemente referida como um “mini-aplicativo”

O seguinte exemplo cria um roteador como um módulo, carrega o middleware nele, define algumas rotas, e monta-o em um caminho no aplicativo principal.

Por exemplo, cria um arquivo roteador chamado birds.js no diretório do aplicativo, com o conteúdo a seguir:


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

// middleware specific to this router
router.use(function timeLog(req, res, next) {
  console.log('Time: ', Date.now());
  next();
});
// define the home page route
router.get('/', function(req, res) {
  res.send('Birds home page');
});
// define the about route
router.get('/about', function(req, res) {
  res.send('About birds');
});

module.exports = router;

Em seguida, carregue o módulo roteador no aplicativo:


var birds = require('./birds');
...
app.use('/birds', birds);

O aplicativo será agora capaz de manipular solicitações aos caminhos /birds e /birds/about, e irá chamar o middleware timeLog que é específico para a rota.

Outras mudanças

A seguinte tabela lista outras pequenas, porém importantes, mudanças no Express 4:

Objeto Descrição
Node.js O Express 4 requer o Node.js 0.10.x ou posterior e descartou o suporte ao Node.js 0.8.x.

http.createServer()

O módulo http não é mais necessário, a não ser que você precise trabalhar diretamente com ele (socket.io/SPDY/HTTPS). O aplicativo pode ser iniciado usando a função app.listen().

app.configure()

A função app.configure() foi removida. Use a função process.env.NODE_ENV ou app.get('env') para detectar o ambiente e configurar o aplicativo de acordo com ele.

json spaces

A propriedade de aplicativo json spaces está desativada por padrão no Express 4.

req.accepted()

Use req.accepts(), req.acceptsEncodings(), req.acceptsCharsets(), e req.acceptsLanguages().

res.location()

Não resolve mais URLs relativas.

req.params

Era uma matriz; agora é um objeto.

res.locals

Era uma função; agora é um objeto.

res.headerSent

Mudado para res.headersSent.

app.route

Agora disponível como app.mountpath.

res.on('header')

Removido.

res.charset

Removido.

res.setHeader('Set-Cookie', val)

A funcionalidade é agora limitada a configurar o valor básico do cookie. Use res.cookie() para funcionalidades adicionais.

Exemplo de migração de aplicativo

Aqui está um eemplo de migração de um aplicativo Express 3 para o Express 4. Os arquivos de interesse são app.js e package.json.

Aplicativo da Versão 3

app.js

Considere um aplicativo do Express v.3 com o seguinte arquivo app.js:


var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.methodOverride());
app.use(express.session({ secret: 'your secret here' }));
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
app.get('/users', user.list);

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

package.json

O arquivo package.json que acompanha a versão 3 pode parecer com algo assim:


{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "3.12.0",
    "jade": "*"
  }
}

Processo

Comece o processo de migração instalando os middlewares necessários para o aplicativo Express 4 e atualizando o Express e o Jade para as suas respectivas versões mais recentes com o seguinte comando:


$ npm install serve-favicon morgan method-override express-session body-parser multer errorhandler express@latest jade@latest --save

Faça as seguintes alterações no app.js:

  1. As funções de middleware integradas do Express express.favicon, express.logger, express.methodOverride, express.session, express.bodyParser e express.errorHandler não estão mais disponíveis no objeto express. É preciso instalar manualmente as alternativas e carregá-las no aplicativo.

  2. Não é mais necessário carregar a função app.router. Ela não é um objeto válido para aplicativos Express 4, portanto remova o código do app.use(app.router);.

  3. Certifique-se deque as funções de middleware sejam carregadas na ordem correta - carregar a errorHandler após carregar as rotas de aplicativo.

Aplicativo da Versão 4

package.json

A execução do comando npm acima irá atualizar o package.json como a seguir:


{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "body-parser": "^1.5.2",
    "errorhandler": "^1.1.1",
    "express": "^4.8.0",
    "express-session": "^1.7.2",
    "jade": "^1.5.0",
    "method-override": "^2.1.2",
    "morgan": "^1.2.2",
    "multer": "^0.1.3",
    "serve-favicon": "^2.0.1"
  }
}

app.js

Em seguida, remova o código inválido, carregue o middleware necessário e faça outras alterações conforme necessárias. O arquivo app.js irá parecer com isso:


var http = require('http');
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var path = require('path');

var favicon = require('serve-favicon');
var logger = require('morgan');
var methodOverride = require('method-override');
var session = require('express-session');
var bodyParser = require('body-parser');
var multer = require('multer');
var errorHandler = require('errorhandler');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(methodOverride());
app.use(session({ resave: true,
                  saveUninitialized: true,
                  secret: 'uwotm8' }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(multer());
app.use(express.static(path.join(__dirname, 'public')));

app.get('/', routes.index);
app.get('/users', user.list);

// error handling middleware should be loaded after the loading the routes
if ('development' == app.get('env')) {
  app.use(errorHandler());
}

var server = http.createServer(app);
server.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

A não ser que precise trabalhar diretamente com o módulo http (socket.io/SPDY/HTTPS), carregá-lo não é necessário, e o aplicativo pode ser iniciado simplesmente desta forma:

app.listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

Execute o aplicativo

O processo de migração está concluído, e o aplicativo é agora um aplicativo Express 4. Para confirmar, inicie o aplicativo usando o seguinte comando:


$ node .

Carregue http://localhost:3000 e veja a página inicial sendo renderizada pelo Express 4.

Fazendo o upgrade para o gerador de aplicativos do Express 4

A ferramenta de linha de comandos para gerar um aplicativo Express ainda é a express, mas para fazer o upgrade para a nova versão , é preciso desinstalar o gerador de aplicativos Express 3 e, em seguida, instalar o novo express-generator.

Instalação

Se já tiver o gerador de aplicativos do Express 3 instalado no seu sistema, é preciso desinstalá-lo:


$ npm uninstall -g express

Dependendo de como os seus privilégios de arquivos e diretórios estão configurados, pode ser necessário executar este comando com sudo.

Agora instale o novo gerador:


$ npm install -g express-generator

Dependendo de como os seus privilégios de arquivos e diretórios estão configurados, pode ser necessário executar este comando com sudo.

Agora o comando express no seu sistema está atualizado para o gerador do Express 4.

Mudanças no gerador de aplicativos

As opções e o uso do comando permanecem em grande parte as mesmas, com as seguintes exceções:

Exemplo

Execute o seguinte comando para criar um aplicativo do Express 4:


$ express app4

Se olhar o conteúdo do arquivo app4/app.js, você verá que todas as funções de middleware (exceto express.static) que são requeridas pelo aplicativo estão a carregadas como módulos independentes, e o middleware de router não está mais explicitamente carregado no aplicativo.

Você irá também notar que o arquivo app.js é agora um módulo do Node.js, ao invés do aplicativo independente gerado pelo antigo gerador.

Após instalar as dependências, inicie o aplicativo usando o seguinte comando:


$ npm start

Se olhar o script de inicialização npm no arquivo package.json, você irá notar que o comando real que inicia o aplicativo é o node ./bin/www, que antes era node app.js no Express 3.

Como o arquivo app.js que foi gerado pelo gerador do Express 4 é agora um módulo do Node.js, ele não pode mais ser iniciado independentemente como um aplicativo (a não ser que modifique o código). O módulo deve ser carregado em um arquivo Node.js e iniciado através do arquivo Node.js. O arquivo Node.js é ./bin/www neste caso.

Nem o diretório bin e nem o arquivo sem extensão www são obrigatórios para a criação ou inicialização de um aplicativo Express. Eles são apenas sugestões feitas pelo gerador, portanto fique a vontade para modificá-los para adequá-los às suas necessidades.

Se livre do diretório www e mantenha as coisas “da maneira do Express 3”, exclua a linha que diz module.exports = app; no final do arquivo app.js, em seguida cole o seguinte código em seu lugar:


app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
  debug('Express server listening on port ' + server.address().port);
});

Assegure-se de carregar o módulo debug em cima do arquivo app.js usando o seguinte código:


var debug = require('debug')('app4');

Em seguida, mude o "start": "node ./bin/www" no arquivo package.json para "start": "node app.js".

Você agora moveu a funcionalidade do ./bin/www de volta para o app.js. Esta mudança não é recomendada, mas o exercício ajuda você a entender como o arquivo ./bin/www funciona, e porque o arquivo app.js não é mais iniciado por conta própria.